【问题标题】:How to delete documents from Firestore from different collections如何从不同集合中的 Firestore 中删除文档
【发布时间】:2021-11-14 19:40:30
【问题描述】:

所以我在 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.js firebase google-cloud-firestore


    【解决方案1】:

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

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

    更具体地说,在您的情况下,您需要循环 assignedToMe 子集合以删除它包含的所有文档。您可以将所有delete() 操作分组到一个Batched Write 中,如下所示:

      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 个操作。如果您计划拥有超过 499 个文档的 assignedToMe 子集合(批量写入也会删除用户文档),则需要使用 Promise.all()

    【讨论】:

    • 嗨@Renaud,我粘贴代码后出现此错误,“消息”:“db.collection(...).doc(...).collecion is not a function db.collection(...).doc(...).collecion 不是函数”
    • 有一个错字:collecion应该是collection
    • 非常感谢,它运行良好(y)
    • 如果获取或提交操作失败,这不会以当前形式抛出 UnhandledPromiseRejection 吗?
    • 这是一个很好的评论@samthecodingman。我不得不承认,有时我只关注答案中的“关键”功能方面而没有提供“辅助”元素......答案已改编:-)
    猜你喜欢
    • 2018-03-22
    • 1970-01-01
    • 2018-10-19
    • 2020-09-08
    • 2021-06-11
    • 2020-11-11
    • 2018-07-20
    相关资源
    最近更新 更多