How Delete a Collection or Subcollection from Firestore

Delete a Document with all Subcollections and Nested Subcollections in Firestore

according to firebase documentation:

https://firebase.google.com/docs/firestore/solutions/delete-collections

Deleting collection with nested subcollections might be done easy and neat with node-JS on the server side.

const client = require('firebase-tools');
await client.firestore
.delete(collectionPath, {
project: process.env.GCLOUD_PROJECT,
recursive: true,
yes: true
});

how to delete a complete collection including sub-collection in firebase firestore

As @danh pointed out, according to the documentation, when you delete a document, Cloud Firestore does not automatically delete the documents within its subcollections.

If you want to delete a document and all the documents within its subcollections, you must do so manually [1].

To delete an entire collection or subcollection in Cloud Firestore, retrieve all the documents within the collection or subcollection and delete them [2].

[1] - https://firebase.google.com/docs/firestore/manage-data/delete-data#delete_documents

[2] - https://firebase.google.com/docs/firestore/manage-data/delete-data#collections

What's the best way to delete collections and subcollections on Firestore?

As stated in the current documentation, deleting from the client is not advised. However, that statement is a bit of an absolute and really needs clarity; it's very use case dependent.

The big picture from Firebase:

There is no single operation in the API to delete an entire
collection. Instead a collection comes into existence once a first
document is added to it, and a collection disappears once the final
document is deleted from it.

So, deleting via the client is possible and is sometimes a solution

HOWEVER, a clear understanding of the ramifications is important. There are many but here are some to consider:

Deleting a collection requires deleting the documents. In some cases that would mean downloading ALL of the documents to get their path which could overwhelm the device.

Along with that, a big download could drive up costs along with possibly affecting the user experience.

To be clear

deleting a collection is ok but may not scale well depending on the size of the collection

e.g. if you need to delete a collection that has 10 documents and will not scale, no problem. But if that collection scales to 1M documents that's a different use case and has a different solution.

So wrapping back to the question:

  1. When I delete an Observation I need to remove the associated image from the Storage.

The key here is "an observation" meaning 1. Yes, it is perfectly acceptable to delete this from the client as '1' is well... '1' and does not scale.


  1. When I delete a Visit I need to delete all it's Observations and their respective images.

This is use case dependent: as of now you're getting all the documents and deleting via iteration. That's what should be avoided because it doesn't scale with an open ended number of documents ...but... if you've limited visits to say 100, then it's not going to scale past that so deleting from the client is ok. If there is NO limit, then deleting from a cloud function is the way to go.


  1. When I delete a Project I need to delete all it's Visits, then all it's Observations and their respective images.

This really depends on what limits you've set for the data within a Project. If it's limited to X number of documents and X is a reasonable number then deleting from the client is okay. However, if there are no limits, leveraging cloud functions is your best bet.

There is NO reason why the two can't be combined as well. For 1, delete from the client. For 2 & 3 delete via cloud functions if the data can scale to a large number.

All that being said, Cloud functions have limitations too - the call can take a while so if there are client side queries running, you can end up with fragmented data. Also, you don't have a status or control over the length of time it will take so it could conceivably time out, then you're in a weird state with some stuff deleted and some stuff not.

Lastly, the cloud based deletions are not transactional, so some data may be deleted and some may not. That should be very very rare but the potential exists.

How delete a collection or subcollection from Firestore?

There is no need to restructure your database in order to delete some collections. To delete an entire collection or subcollection in Cloud Firestore, retrieve all the documents within the collection or subcollection and delete them. So in order to delete a specific list, please use the following steps:

  1. Find all documents beneath employees collection and delete them
  2. Find all documents beneath locations collection and delete them
  3. Delete the listId document

If you have larger collections, you may want to delete the documents in smaller batches to avoid out-of-memory errors. Repeat the process until you've deleted the entire collection or subcollection.

Even if the delete operation is not recomended by Firebase team because it has negative security and performance implications, you can still do it but only for small collections. If you need to delete entire collections for web, do so only from a trusted server environment.

For Android, you can use the following code:

private void deleteCollection(final CollectionReference collection, Executor executor) {
Tasks.call(executor, () -> {
int batchSize = 10;
Query query = collection.orderBy(FieldPath.documentId()).limit(batchSize);
List<DocumentSnapshot> deleted = deleteQueryBatch(query);

while (deleted.size() >= batchSize) {
DocumentSnapshot last = deleted.get(deleted.size() - 1);
query = collection.orderBy(FieldPath.documentId()).startAfter(last.getId()).limit(batchSize);

deleted = deleteQueryBatch(query);
}

return null;
});
}

@WorkerThread
private List<DocumentSnapshot> deleteQueryBatch(final Query query) throws Exception {
QuerySnapshot querySnapshot = Tasks.await(query.get());

WriteBatch batch = query.getFirestore().batch();
for (DocumentSnapshot snapshot : querySnapshot) {
batch.delete(snapshot.getReference());
}
Tasks.await(batch.commit());

return querySnapshot.getDocuments();
}

Deleting a sub-collection in Firebase -Flutter

To delete all documents in collection or subcollection with Cloud Firestore, you can use the delete method iterating on a DocumentReference:

CollectionReference users = FirebaseFirestore.instance.collection('users');

Future<void> deleteAllTaskDocs() {
return users
.doc(user.uid)
.collection('Tasks')
.get()
.then((QuerySnapshot querySnapshot) {
querySnapshot.docs.forEach((doc) {
doc.reference.delete();
});
});
}

Keep in mind that:

  • There is no operation that atomically deletes a collection.
  • Deleting a document does not delete the documents in its subcollections.
  • If your documents have dynamic subcollections, it can be hard to know what data to delete for a given path.
  • Deleting a collection of more than 500 documents requires multiple batched write operations or hundreds of single deletes.

deleting a collection that includes a nested sub collection in firebase?


the problem is that the (data-set-c) collection never gets deleted.

That's the expected behavior. If you delete a document, doesn't mean that you delete all sub-collections that exist within that document. Besides that, that document ID will continue to exist and the Firebase Console will display it in italic.

will deleting this way affect also sub-collection?

No, it won't.

or is it the rules that are blocking it since my rules are specific to the deepest level endpoint.

If it was about the security rules, then you would have received an error indicating that.

or should use cloud function instead since this doc will be massive later on

Yes, you can indeed use a Cloud Function to delete all documents that exist in all sub-collection of the document that was deleted.

How to delete this one-level nested structure.

You can achieve this by iterating each sub-collection, and by deleting each document. But don't do it on the client!

How to delete nested collections from an empty document in Firestore?

After some digging, I found that you can use the firebase-cli with the --recursive tag to recursively delete the entire collection and subcollections as follows:

firebase firestore:delete "foo/bar" --recursive --project=PROJECT_ID


Related Topics



Leave a reply



Submit