I'm building an e-commerce app but when I query firestore to retrieve data I get documents length 0. Data Is present in Firestore. I have no idea what is causing this issue.
I have added all the dependencies.
Firestore.instance
.collection('Products')
.getDocuments().then((value) => print(value.documents.length));
Why this query is not giving me a total number of documents inside Products.
When I run this Query I get a Correct number of documents inside Fruits.
Firestore.instance
.collection('Products')
.document('ABHISHAK FRUITS').collection('Fruits').getDocuments().then((value) => print(value.documents.length));
The log message is correct - your first query returned no documents.
Notice that IDs of the documents in the console are in italics. This means that the document is not present. The reason why the console is showing these missing documents is because the document ID has a subcollection nested under it, and it's letting you click through to browse them.
Your second query using the subcollection works fine because the subcollection has documents present in it.
The bottom line here is that subcollections are not really "contained" within their parent documents like a traditional computer filesystem. The parents documents can be created or deleted without affecting the any subcollections nested under them.
Related
Trying to fetch the all documents present in Users Collections but receiving empty list and when i tried to fetch Documents from Admins collections its working fine.
this._fs
.collection(FBMainCollection.Users)
.get()
.subscribe((usr) => {
const data = usr.docs.map((e) => e.data());
console.log(data);
});
Response
[]
empty list
Unable to fetch documents from a few collections.
working only for collections which doesn`t have nested collections;
Your screenshot shows that you don't have any documents in the Users collection. Notice how all of the document IDs are in italics, and none of them have any fields. That means there is no document there, but there is a nested subcollection under it that you can navigate into. Queries do not read any of the nested subcollections, so instead it just shows and empty collection..
See also:
Firestore document/subcollection is not existing
Why are non auto-generated document Ids are in italics in Firestore console?
I have a nested collection in firestore that I want to make a query from it.
As you can see the first collection called 'businessUsers' and the nested one called 'campaigns',
If I make a query for a field in the 'businessUsers' it's working OK:
return FirebaseFirestore.instance.collection("businessUsers").where('xxx',
isEqualTo:filterBusinessResult ).snapshots().map(_businessListFromSnapshot);
but how can I make a query to 'campaigns' collection field?
I tried
return FirebaseFirestore.instance.collection("businessUsers").doc().collection("campaigns").where('campaignCategory', isEqualTo:filterBusinessResult ).snapshots()
.map(_businessListFromSnapshot);
but it wont work.
Its important to note, that I need all the data with 'campaignCategory' == filterBusinessResult
any idea?
It depends on whether you want to query a specific user's campaigns, or the campaigns of all users together.
If you want to query the campaigns of a specific user, you need to query under their document:
FirebaseFirestore.instance
.collection("businessUsers").doc("your user ID").
.collection("campaigns")
.where('campaignCategory', isEqualTo:filterBusinessResult)
So you have to know the ID of the businessUsers document here.
If you want to query across all campaigns subcollections are once, that is known as a collection group query and would look like this:
FirebaseFirestore.instance
.collectionGroup("campaigns")
.where('campaignCategory', isEqualTo:filterBusinessResult)
The results are going to documents from the campaigns collection only, but you can look up the parent document reference for each DocumentSnapshot with docSnapshot.reference.parent.parent.
When querying something, .doc() requires the id of the document you're trying to get. So it's failing because it doesn't know which document in the businessUsers collection you're trying to fetch a subcollection on. You probably want to use a .collectionGroup() query here. They let you query all subcollections at once (see documentation here). With FlutterFire specifically, it's going to be something like:
var snapshots = FirebaseFirestore.instance.collectionGroup("campaigns")
.where("campaignCategory", isEqualTo: filterBusinessResult)
.snapshots();
I am trying to create a document and collection following each other
with this reference
CollectionReference att = FirebaseFirestore.instance
.collection('attendance/$_currentClass/pieces');
but when it is created it is shown like that image below
and i can't see documents that has name of "_currentClass" variable.
If we create create it by ourselves it creates properly.
Here top one was created by me and bottom one created inside flutter
What am i doing wrong?
Based on your path your CollectionReference to this subcollection is:
CollectionReference att = FirebaseFirestore.instance
.collection('attendance')
.doc(_currentClass)
.collection('pieces');
Document, you are pointing with italic font does not exist, it was deleted, but before that it had a collection, and pointing that documents on that subcollection were not deleted and they still exist.If you create documents with sub-documents and then delete the top level document from an SDK, the delete is not recursive. So while the top-level document is gone, its sub-documents remain.
Since there is no document anymore, the document itself will not show up in query results. If you need to find this document in query results, you'll want to create an empty document as a workaround.
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.
I'm using Firebase Cloud Firestore and can't figure out how to access documents without knowing the specific path. The database structure is users/{user id}/favourites/{favourite id}. There are no fields in users/{user id} only subcollections. Knowing the user id, i can get the favourites for the user, but I can't get a list of users to get everyone's favourites. Here is the code I am trying (Java admin SDK):
db.collection("users").get().get()
which results in an empty Iterable with no DocumentSnapshots.
How can I get a list of the most popular favourites?
EDIT: I've discovered I can get a list of users with no fields if I add a field. Even if I delete it later, it still appears as a document in the collection.
EDIT2: I've discovered that I can create an empty document, so I'm just doing that for now. As a one-off, I can get a list of all users from firebase auth and look up which ones have a favourites collection and just set those to empty documents.