How delete a collection or subcollection from Firestore?
I have a collection called lists and it has documents who is ID represents the list ID. This document has a collection called employees
and another one called locations
.
The structure looks like this:
(lists)
-listId
(employees)
(locations)
If the user wants to delete a specific list then the problem is that we can't delete listId because that will keep the collection (as was mentioned by Firestore docs).
How can the structure be modeled to fit the needs? I can't seem to get around the need for subcollection.
Any recommendation?
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:
- Find all documents beneath
employees
collection and delete them - Find all documents beneath
locations
collection and delete them - 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();
}