如何在Firestore中递归删除集合?

11
我需要一种快速清除整个Firestore数据库的方法,但是找不到很好的文档来说明如何做到这一点。最终我在stackoverflow上找到了这个答案(清除Firestore数据库中的所有数据?),但是我对清除数百万个文档的整个数据库需要多长时间感到有些紧张,所以我希望能够一次递归地删除一个集合。
背景:我一直在运行一些测试,将大量数据从旧数据库迁移到Firestore,每次运行后,我希望在Firestore中有一个干净的起点。请不要在生产数据上使用这个方法!
3个回答

41

现在可以使用 recursiveDelete 函数来实现此操作:

请注意,这是一个相对较新的功能,所以您需要确保您的 Firebase 库已经更新。

// Setup
const admin = require('firebase-admin');
const serviceAccount = require("./files/my-file.json");
admin.initializeApp({
  credential: admin.credential.cert(serviceAccount)
});
const firestore = admin.firestore();

// Delete
const documentRef = firestore
      .collection("users")
      .doc("M3S2iPhsiu2ZQmOK8ZcC");
await firestore.recursiveDelete(documentRef);

4
哇,这真的很美。我希望这个问题和答案能够被推到 S.O. 的顶部,以便删除子集合。我觉得这里98%的答案仍然解释了批量删除子集合中单个文档的过程,而这种方式非常麻烦。对我来说,这种方法快速而且效果很好。 - Tristan Bennett
即使 Firebase 文档仍然说您必须自己递归遍历文档/集合。 - Spock
1
很棒的答案!我很高兴找到了它。 - Nobadi
@kgaid的recursiveDelete有任何限制吗? - Sohel Islam Imran
2
奇怪的是这个还没有在文档中,但请确保升级您的Firebase管理SDK,否则您将无法访问此内容。 - max

3

我通过运行firestore cli delete命令并指定每个集合的路径来实现此操作。请勿以斜杠开头,否则它会认为您要删除计算机上的目录。以下是示例:

firebase firestore:delete "path/to/collection" --recursive

firestore:delete 命令在这里也有一定的文档介绍:https://firebase.google.com/docs/firestore/manage-data/delete-data#delete_data_with_the_firebase_cli

更新信息:请注意,在删除大约 20000 个文档后,该命令可能会失败。我认为它可能会达到某个限制。我只需多次使用相同的集合路径重新运行即可完全删除大于 20k 文档的集合。


你的回答非常简单明了,而且非常有用!现在是我首选的方法 :) - Tristan Bennett

1

来自 Fireship 网站:https://fireship.io/snippets/delete-firestore-collection/,在 Firestore 中删除集合有两种选项:

选项 1:您可以手动从 Firebase 控制台或使用 CLI 删除集合或子集合:

firebase firestore:delete path-to-delete

选项 2:

可以从云函数与 Firebase 工具进行交互。与可调用函数相结合效果尤佳,因为您肯定想要强制执行某种形式的用户授权。 首先,获取 CI 令牌以验证 firebase 工具。

cd functions
npm i firebase-tools -D

firebase login:ci
# your_token

firebase functions:config:set ci_token='your_token'

该函数应验证用户是否有权限运行操作。如果允许,则在集合及其嵌套的子集合上递归运行CLI命令。
const project = process.env.GCLOUD_PROJECT;
const token = functions.config().ci_token;

exports.deleteCollection = functions.runWith({ timeoutSeconds: 540})
  .https.onCall((data, context) => {

  const path = data.path;
  const allowed = context.auth.uid === path.split('/')[0]; // TODO your own logic

if (!allowed) {
  throw new functions.https.HttpsError(
    'permission-denied',
    'Hey, that is not cool buddy!'
  );
}

return firebase_tools.firestore
  .delete(path, {
    project,
    token,
    recursive: true,
    yes: true,
  })
  .then(() => ({ result: 'all done!' }));
});

这是专门以管理员身份运行此命令。Firebase控制台在删除大型集合时非常缓慢,因此我不建议使用它。云函数具有运行时和资源限制,因此我也不建议用于非常大的集合。 - Alex Egli

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接