Home > Enterprise >  How to delete documents from Firestore from different collections
How to delete documents from Firestore from different collections

Time:09-21

So I have 2 collections in firestore,

  1. Users (collection)
  2. Inspection (collection)

Users have only documents named as different email addresses Inspection have documents named as different email addresses and then each document have another collection named "assignedToMe" and then this collection have different documents named as some unique ids.

What I want to do is whenever I delete a user, I want its document named as his email address to be deleted as well from Inspection(collection).

The issue I'm having here is I am able to delete the user from Users(collection) but unable to delete the document in Inspection(collection) for that particular user, here's my code and a structure of 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.");
  }
}); 

enter image description here

enter image description here

CodePudding user response:

The Inspection documents are displayed in an italic font in the console: this means that these documents are only present as "containers" of the assignedToMe subcollection but that they are not "genuine" documents. See more info in this answer.

In addition, deleting a document does not delete the documents present in its subcollections, as also explained in the linked answer. You have to delete the subcollections documents as well.

More concretely, in your case, you need to loop over assignedToMe subcollection in order to delete all the documents it contains. You can group all the delete() operations in a Batched Write, as follows:

  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));
    }
  });

Note that a batched write can contain up to 500 operations. If you plan to have assignedToMe subcollections with more than 499 documents (the batched write also deletes the user doc), you would need to use Promise.all().

  • Related