delete a collection and all the including data (collections and fields) - firebase

Im trying to delete a document X in collection Users but in this collection, there is another collection tasks is the collection Users. How can I delete all the data in the document X (includes collection tasks)
firebase.firestore().collection("Users").doc(X).delete();

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.
This means that you'll need to delete each document in the collection individually, preferably using batch delete operations. Once you've deleted the last document from the subcollection, the collection itself is also gone.

Related

Get parent collection & sub collection document on firebase

I'm new to firebase I had 2 collection categories & products and the product collection, has a sub-collection Category, how can I get all documents from the product collection and sub-collection category? thank in advance
There is no way to read from both the parent collection and the sub collection in one operation. Read always come from one (type of) collection, which is sometimes explained as "all reads in Firestore are shallow".
You can either:
Read the parent collection, and then for each (relevant) document read its subcollection as a separate operation.
Read the parent collection, and read all SubCategory collections in one go with a collection group query.
The second approach performs fewer calls to the server, but has a higher chance of reading more documents than needed, if (for example) you may not want the SubCategory collection from some documents.

Firestore - Batch querying nested documents in REST API

There is a way to batch get documents after you specified exactly all the file paths using
https://firestore.googleapis.com/v1/projects/projectName/databases/dbName/documents:batchGet.
And there is a way to get all documents and their fields under a collection by sending a GET to https://firestore.googleapis.com/v1/projects/projectName/databases/dbName/documents/collectionName
I ideally want to make a batch request to get document fields for all documents under an array of collections. Is there a way to do this without knowing the document names of every document I intend to get?
Example
I have a structure like projects/projectName/databases/dbName/documents/Inventory/productId/variantId/*location*
Each productId is a document, and under this it has a collection for each variant, and within that collection are documents for each location, that contains a field count.
For a basket, I want to get all inventory counts for all inventory locations, for each productId/variantId in that bas
It is not possible to get all documents based on an array of collection names.
You can use a collection group query and search all collections of a given name, but then you must know the path of each document you want to read.
Alternatively, you can get all documents under a specific path, but then you can't filter by ID anymore, and the collections have to be under a path - not an array.

Unable to delete an item from multiple collections in firebase

I have two collection in firebase, say A and B. When I add an item to one of the collections, say A, it automatically adds to another collection B. But when I delete an item from collection A, it remains in the other collection B.
Shot from firebase console
When I delete an item from collection A, it remains in the other collection B.
I am unable to figure out how to make the items deleted in both collections?
Please help.
This is no relational DB. Cascadate updates/deletes are possible in relational DBs like Sql, Postgresql, Firebird... In No-SQL You do not have any relations one document to another. What' more it is desirable to have some data cloned in two or more documents rather than creating a separate doc for it.
But maybe You can achieve what You want by using reference type? I sow it once or twice, it might be a good idea to check it out. But be the description it is only a field with path/reference, no magic here.
By the official doc:
If you want to delete documents in subcollections when deleting a parent document, you must do so manually, as shown in Delete Collections.
So You either want to rethink The DB model or have to manualy track each wlement You want to delete.
You have two ways to do that:
From client side use batch write (more here)
DocumentReference doc_1_reference = firestore.collection("messages").document(doc_1_uid);
DocumentReference doc_2_reference = firestore.collection("messages").document(doc_2_uid);
final batchWrite = firestore.batch();
batchWrite.delete(doc_1_reference);
batchWrite.delete(doc_2_reference);
await batchWrite.commit();
Using Cloud functions by adding a delete trigger to the documents, and perform the deletion of the other document when triggered. Given you have away to know which document you're supposed to delete which is not difficult to do (read about it here)

What is the recommended way to track document changes in firestore?

Let's say I have a employees collection where I have one document per employee and I want to keep record of all changes that were made to a single employee doc. I was thinking of the following approach:-
Have a pendingEmployeeWrites collection where client is
only allowed to create documents. Each doc here will have an
employeeId field (this id is generated on client side for new employees).
Cloud function will be invoked whenever such a doc is created and then it validates the data. If valid, the employeeId doc in employees collection is overwritten with this data. Otherwise the pendingEmployeeWrites doc is updated to set isFailed as true. Client app is only allowed to read from employees collection.
Keeping pendingEmployeeWrites as a flat collection instead of a sub-collection allows me to pull all changes made by a user as well as all changes for a particular document. Does this approach make sense or is there a better approach that I should consider?

Firestore query for subcollections on a deleted document

When using the Firebase console it is possible to see all documents and collections, even subcollections where the path has "documents" that do not exist.
This is illustrated in the picture included here, and as stated in the docs and on the screenshot as well. These documents won't appear in queries or snapshots. So how does the console find these nested subcollections, when a query does not return them?
Is it possible, somehow, to list these documents. Since the console can do it, it seems there must be a way.
And if it is possible to find these documents, is it possible to create a query that fetches all the documents that are non-existant but limited to those that have a nested subcollection? (Since the set of all non-existant documents would be infinite)
The Admin SDK provides a listDocuments method with this description:
The document references returned may include references to "missing
documents", i.e. document locations that have no document present but
which contain subcollections with documents. Attempting to read such a
document reference (e.g. via .get() or .onSnapshot()) will return a
DocumentSnapshot whose .exists property is false.
Combining this with the example for listing subcollections, you could do something like the following:
// Admin SDK only
let collectionRef = firestore.collection('col');
return collectionRef.listDocuments().then(documentRefs => {
return firestore.getAll(documentRefs);
}).then(documentSnapshots => {
documentSnapshots.forEach(doc => {
if( !doc.exists ) {
console.log(`Found missing document: ${documentSnapshot.id}, getting subcollections`);
doc.getCollections().then(collections => {
collections.forEach(collection => {
console.log('Found subcollection with id:', collection.id);
});
});
}
});
});
Note that the Firebase CLI uses a different approach. Via the REST API, it queries all documents below a given path, without having to know their specific location first. You can see how this works in the recursive delete code here.
Is it possible to create a query that fetches all these subcollections that are nested under a document that does not exist.
Queries in Cloud Firestore are shallow, which means they only get documents from the collection that the query is run against. There is no way in Cloud Firestore to get documents from a top-level collection and other collections or subcollections in a single query. Firestore doesn't support queries across different collections in one go. A single query may only use properties of documents in a single collection or subcollection.
So in your case, even if one document does not exist (does not contain any properties), you can still query a collection that lives beneath it. With other words, you can query the queue subcollection that exist within -LFNX ... 7UjS document but you cannot query all queue subcollection within all documents. You can query only one subcollection at a time.
Edit:
According to your comment:
I want to find collections that are nested under documents that do not exist.
There is no way to find collections because you cannot query across different collections. You can only query against one. The simplest solution I can think of is to check if a document within your items collection doesn't exist (has no properties) and then create a query (items -> documentId -> queue), and check if has any results.
Edit2:
The Firebase Console is telling you through those document ids shown in italics that those documents just does not exist. Those documents do not exist because you didn't create them at all. What you did do, was only to create a subcollection under a document that never existed in the first place. With other words, it merely "reserves" an id for a document in that collection and then creates a subcollection under it. Typically, you should only create subcollections of documents that actually do exist but this is how it looks like when the document doesn't exist.
In Cloud Firestore documents and subcollections don't work like filesystem files and directories you're used. If you create a subcollection under a document, it doesn't implicitly create any parent documents. Subcollections are not tied in any way to a parent document. With other words, there is no physical document at that location but there is other data under the location.
In Firebase console those document ids are diplayed so you can navigate down the tree and get the subcollections and documents that exist beneath it. But in the same time the console is warning you that those document does not exist, by displaying their ids in italics. So you cannot display or use them because of the simple fact that there is no data beneath it. If you want to correct that, you have to write at least a property that can hold a value. In that way, those documents will hold some data so you can do whatever you want.
P.S. In Cloud Firestore, if you delete a document, its subcollections will continue to exist and this is because of the exact same reason I mentioned above.

Resources