I am querying my Firestore database as follows:
final Query roasters = Firestore.instance
.collection('retailers')
.where('retail_category', isEqualTo: 'Coffee Roasters');
I am receiving the result back of all documents in the retailers collection which have 'retail_category' set as 'Coffee Roasters'.
The Problem
I instead want to turn retail_category into a separate collection and instead reference it in the retailer field (which would negate the following reference):
"retail_categories/hEN5fzNl2hEc2tEs05Wi"
I have tried the following:
final Query roasters = Firestore.instance
.collection('retailers')
.where('retail_categories', isEqualTo: ' qretail_categories/hEN5fzNl2hEc2tEs05Wi');
Here is my Firestore configuration:
Retailers
Retail Categories
It's not possible to reference data in documents outside of the collection being used for the query. For this reason, it's very common to duplicate data between documents that need to be used in queries for each collection. If you don't want to do that, you will have to make separate queries for each referenced document.
Related
Is there any way to retrieve a collection along with its sub-collections from Firebase Firestore using Flutter?
fetchTestSite() async {
return await FirebaseFirestore.instance
.collection('sites')
.doc('4R3aOMBFTjumYCbETDU8')
.get()
.then((DocumentSnapshot doc) {
print('document: ${doc.data()}');
});
}
This code snippet only returns the main collection without the existing sub-collections
Is there any way to retrieve a collection along with its sub-collections from Firebase Firestore using Flutter?
No, there is no way you can do that. Queries in Firestore are shallow. This means that it can only return documents from the collection that the query is run against.
There is no way to get documents from a top-level collection and sub-collections in a single query. You can only get documents from a single collection.
However, there is a "hack" that can be made. If you want to get the data from the sub-collection that corresponds to a specific document, you can use a collectionGroup to get documents under a certain path. I explained in the following article:
How to query collections in Firestore under a certain path?
How you can do that and what limitations you might have.
If you consider at some point in time try using the Firebase Realtime Database, what you are looking for it's possible, because when you attach a listener on a specific node, you download all the data beneath it.
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();
This is my data structure. Here are the list of users documents.
and here is the subcollection in every document.
The subcollection is containing strongly typed document which is form.
What I want is to fetch form document (not for the current user) from subcollection workerField from every users document.
what is the implementation method.
If you want to load documents from all workerField collections you can use a so-called collection group query.
So something like:
var docs = await FirebaseFirestore.instance
.collectionGroup('workerField')
.snapshots();
See my answer here for another example: Is wildcard possible in Flutter Firestore query? and more from these search results.
I am trying to get non empty Rooms from Buildings Collection from Firebase Firestore ( Using Flutter Framework):
Query _queryRef = FirebaseFirestore.instance
.collection('Buildings')
.where("isActive", isEqualTo: true)
.where("Rooms", isNotEqualTo : null);
But I am not getting any collections Even though there are few Rooms sub collection records exist in Buildings.
Adding Screenshot for reference-
Queries in Firestore work on a single collection, or on a group of collections of the same name. There is no way to query your Buildings documents on the existence of or values in their Rooms subcollection.
The typical workaround is to store a RoomCount field in each Buildings document, and keep that up to date as you add/remove rooms. With that in place you can query:
FirebaseFirestore.instance
.collection('Buildings')
.where("isActive", isEqualTo: true)
.where("RoomCount", isGreaterThan: 0);
Append .get() at the end of your query. Here you can read more about most common use cases of working with firebase via flutter.
In my firebase's database I have Users and every user has multiple stores that he ordered from and every store has multiple orders.
To fetch all the orders for specific store I write the following query and it works fine.
QuerySnapshot result = await Firestore.instance
.collection('users')
.document(userID)
.collection('Stores').
document(storeID).getDocuments();
However, I do not need that. I just need the stores that the user ordered from. In other words, I need list of storeIDs for specific user.
Here is my code but it doesn't work.
QuerySnapshot result = await Firestore.instance
.collection('users')
.document(userID)
.collection('Stores').getDocuments();
I just want the IDs
It's not possible with web and mobile clients to get only the IDs without the entire set of documents and their data. If you want a list of all IDs for all documents in a collection or subcolleciton, you're going to have to query that collection as you currently show in the second example. You can easily extract the IDs from the returned documents in the QuerySnapshot. But you are still paying the cost of a document read for each document in the collection, and waiting for all of their contents to transfer.
If you want, you can create your own backend endpoint API to use a server SDK to query for only the IDs, and return only the IDs, but you are still paying a document read for document.