skip to Main Content

Every time I try to delete a document programmatically using documentSnapshot.delete(), the firebase only deletes the document and not its subcollections. I want to permanently delete a document and all its subcollections with the push of a button and every time the user tries to create the same document, it’d be empty.

What’s the proper way to do that?

(CLOSED)

This is the code that worked for me:

CollectionReference<Map<String, dynamic>> collectionReference = FirebaseFirestore.instance.collection('collection name').doc('document name').collection('collection name');
DocumentReference<Map<String, dynamic>> documentReference = collectionReference.doc('document name');

documentReference.collection('lists').get().then((lists) {
    lists.docs.forEach((listElement) {
      documentReference.collection('lists').doc(listElement.id.toString()).collection('cards').get().then((cards) {
        cards.docs.forEach((cardElement) {
          documentReference.collection('lists').doc(listElement.id.toString()).collection('cards').doc(cardElement.id.toString()).delete();
        });
      });
      documentReference.collection('lists').doc(listElement.id.toString()).delete();
    });
  });

await documentReference.delete();

2

Answers


  1. Deleting a document does not automatically delete all documents in its sub-collections.

    There is no method in firestore API to delete subcollections along with the document. You need to loop through and delete the documents in subcollections and then delete the parent document.

    Here’s a link for better understanding.

    Login or Signup to reply.
  2. I don’t know Dart but here’s my simple solution with PHP Firestore;

    public function destroyCollection(CollectionReference $collection)
    {
        $documents = [];
        foreach ($collection->listDocuments() as $document) {
            $documents[] = $document;
        }
    
        $this->destroyDocuments($documents);
    }
    
    /**
     * @param DocumentReference[] $documents
     */
    public function destroyDocuments(array $documents)
    {
        if (!$documents) return;
        
        $batch = $this->database->getBatch();
        foreach ($documents as $document) {
            $batch->delete($document);
    
            foreach ($document->collections() as $collection) {
                $this->destroyCollection($collection);
            }
        }
        
        $batch->commit();
    }
    

    It’ll delete all the documents that it finds no matter how deeply nested they are. And non-existing docs won’t show up in snapshots and queries so that’s why I’m using the listDocuments() method even tho I’m sacrificing performance a bit.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search