首页 > 解决方案 > 如何从不同集合中的 Firestore 中删除文档

问题描述

所以我在firestore有2个收藏,

  1. 用户(集合)
  2. 检查(收集)

用户只有被命名为不同电子邮件地址的文档 检查有被命名为不同电子邮件地址的文档,然后每个文档都有另一个名为“assignedToMe”的集合,然后这个集合有不同的文档,命名为一些唯一的 id。

我想要做的是每当我删除一个用户时,我希望它的名为他的电子邮件地址的文档也从检查(集合)中删除。

我在这里遇到的问题是我能够从用户(集合)中删除用户,但无法删除该特定用户的检查(集合)中的文档,这是我的代码和 firestore 的结构。

router.use("/delete", [auth, admin], async function (req, res, next) {
  const { email } = req.body;
  const userRef = db.collection("Users").doc(email);
  const insRef = db.collection("Inspection").doc(email);

  const user = await userRef.get();
  const inspection = await insRef.get();

  if (!user.exists) {
    return res.status(404).send("This user has already been deleted!");
  } else {
    const result = userRef.delete();
    if (!inspection.empty) {
      const myres = insRef.delete();
    }
    result && res.status(200).send("User deleted successfully.");
  }
}); 

在此处输入图像描述

在此处输入图像描述

标签: node.jsfirebasegoogle-cloud-firestore

解决方案


Inspection文档在控制台中以斜体字体显示:这意味着这些文档仅作为子集合的“容器”出现,但assignedToMe它们不是“真正的”文档。在这个答案中查看更多信息。

此外,删除文档不会删除其子集合中存在的文档,如链接答案中所述。您还必须删除子集合文档。

更具体地说,在您的情况下,您需要遍历assignedToMe子集合以删除它包含的所有文档。您可以对批量写入delete()中的所有操作进行分组,如下所示:

  router.use('/delete', [auth, admin], async function (req, res, next) {
    try {
      const { email } = req.body;
      const userRef = db.collection('Users').doc(email);

      const user = await userRef.get();

      if (!user.exists) {
        return res.status(404).send('This user has already been deleted!');
      } else {
        const batch = db.batch();

        // Deleting the user doc
        batch.delete(userRef);

        // Deleting the assignedToMe subcollection docs
        const assignedToMeRef = db
          .collection('Inspection')
          .doc(email)
          .collection('assignedToMe');

        const assignedToMeQuerySnapshot = await assignedToMeRef.get();

        assignedToMeQuerySnapshot.forEach((doc) => {
          batch.delete(doc.ref);
        });
        // Note that if the assignedToMe subcollection is empty
        // nothing will be added to the batched write by the previous loop

        await batch.commit();

        result && res.status(200).send('User deleted successfully.');
      }
    } catch (error) {
      console.log(error);
      return res
        .status(500)
        .send('The following error occured: ' + JSON.stringify(error));
    }
  });

请注意,批量写入最多可包含 500 个操作。如果您计划拥有assignedToMe超过 499 个文档的子集合(批量写入也会删除用户文档),则需要使用Promise.all().


推荐阅读