Collection Group query isn't returning any data flutter - flutter

I have set composite index and rules in console but still I'm unable to get any data. Below is snippet of my service for query.
_db.collectionGroup("entries")
.where("instructors", arrayContains: _id.getUser.mailID)
.where("branch", isEqualTo: _id.getBranch.name)
.where("date", isEqualTo: date)
.snapshots();

Related

FirebaseException: Not able to query a collectionGroup

I am trying to do a pretty simple query in firebase for a collectionGroup. I only want to get all the products that are of the type "Restuarant". The code is below:
QuerySnapshot res = await FirebaseFirestore.instance
.collectionGroup('products')
.where("type", isEqualTo: "Restuarant")
.get();
It keeps throwing a FirebaseException as below:
I have added an exception in the Firebase indexes. It is a single field index.
What is the issue here? Why is this Exception occurring?
So I was able to get it working by adding a composite index. After adding the composite index, I was able to perform orderBy query too, using the rating field.
QuerySnapshot res = await FirebaseFirestore.instance
.collectionGroup('products')
.where("type", isEqualTo: "Restuarant")
.orderBy("rating", descending: true)
.get();

Firebase Querying with 'order by' and 'where' returning null

var x = FirebaseFirestore.instance
.collection('Workouts')
.doc(FirebaseAuth.instance.currentUser?.uid)
.collection('allWorkouts')
.orderBy("Date Added", descending: true)
.where("Name", isEqualTo: workout.name)
.limit(limit)
.snapshots();
I have attached the code I am using to query data from my Firestore database. I have a field called 'Date Added' with a space. I have also added the respective index in firebase, with 'Date Added' and 'Name', both being ascending. I get an error below
Is there something I am doing wrong with the query, possibly due to the space in between the 'Date' and 'Added'?
Picture of the DB below where you can see that there are entries.
Try moving the Where clause before the OrderBy clause, like this:
var x = FirebaseFirestore.instance
.collection('Workouts')
.doc(FirebaseAuth.instance.currentUser?.uid)
.collection('allWorkouts')
.where("Name", isEqualTo: workout.name)
.orderBy("Date Added", descending: true)
.limit(limit)
.snapshots();
Also, you mentioned that you created a composite index with Date Added and Name fields both ascending, but you are ordering Date Added as descending, try fixing that index as attached in image

Deleting a Firestore entry based on FIFO

I'm trying to create a script that deletes a record from a Firestore collection using a FIFO (First In First Out approach).
So if there are three matching results in the collection, the script should take the first one added and just delete that one (leaving the remaining two). My code is:
_firestore
.collection('myCollection')
.where('uid',
isEqualTo: _auth.currentUser.uid)
.where('field',
isEqualTo: widget.field)
.orderBy('Posted', descending: false)
.limit(1)
.get()
.then((querySnapshot) {
querySnapshot.docs
.forEach((documentSnapshot) {
_firestore
.collection('myCollection')
.doc(documentSnapshot.id)
.delete();
});
});
(Just to note: 'Posted' is the date the entry was added) Unfortunately this doesn't work, and all three results remain in the collection.
If though I use this script instead, then all three results are removed from the collection:
_firestore
.collection('myCollection')
.where('uid',
isEqualTo: _auth.currentUser.uid)
.where('field',
isEqualTo: widget.field)
.get()
.then((querySnapshot) {
querySnapshot.docs
.forEach((documentSnapshot) {
_firestore
.collection('myCollection')
.doc(documentSnapshot.id)
.delete();
});
});
An example of an entry in my collection is as follows:
So I know the logic, connection, fields etc... are all correct, but why does the first example not work?
Have you check you logs? I am pretty sure that Firebase is throwing an error saying that your collection need indexes with a link.
Just follow the link and the instruction to build the indexes. Once complete you should be able to do what you are looking for.
More info about Indexes: https://firebase.google.com/docs/firestore/query-data/indexing
and Simple queries / Coumpound queries: https://firebase.google.com/docs/firestore/query-data/queries

Search for data/values/keyes in firestore documents

I have a search screen in my app and i want to make sure you can search for every value in a firestore document. There are always 4 Keys in one document: title, author, genre and code.
getBookbyTitel(query) async{
return await Firestore.instance
.collection("book")
.where("titel", isEqualTo: query)
.getDocuments();
}
but with this code, I am only able to search for the title. how can I search for the three other keys a well?
Thanks
getBookbyTitel(query) async{
return await Firestore.instance
.collection("book")
.where("titel", isEqualTo: query).where("author", isEqualTo: query2).where("genre", isEqualTo: query3).
where("code", isEqualTo: query4).getDocuments();
}
Firestore has the advantage of having indexes complex and simple.
getBookbyTitel(query,query2,query3) async{
return await Firestore.instance
.collection("book")
.where("genre", isEqualTo: query)
.where("title", isEqualTo: query2)
.where("code", isEqualTo: query3)
.getDocuments();
There is no actual limit to how many .where() you can use, however this is what is called a "complex query" and as such the first time will fail because firestore needs to index first.
So, first run the code above, in the console an error message will pop up with a url that will send you to your firebase project and then on its own it will start indexing so the next time you run that code it will do it lightning fast.
However there is a downside, for each .where() you use, an additonal indexation will be needed for it to work properly. Have in mind that the order is important too, if you query in order [title,author,genre,code] you should always do it this way, otherwise it will detect it as a completely different query and will ask you to index again.
Finally there is also the issue that for example a more specific query is not the same as a query with less attributes. i.e:
getBookbyTitel(query,query2,query3) async{
return await Firestore.instance
.collection("book")
.where("genre", isEqualTo: query)
.where("title", isEqualTo: query2)
.where("code", isEqualTo: query3)
.getDocuments();
If you have this query, and then you try this instead:
getBookbyTitel(query,query2,query3) async{
return await Firestore.instance
.collection("book")
.where("genre", isEqualTo: query)
.where("title", isEqualTo: query2)
.getDocuments();
It won't work, it will ask you for another index.

Query a Map containing an ID saved in Cloud Firestore with Dart/Flutter

How to get a Map stored in Cloud Firestore with Dart/Flutter ?
I tried this but it only works with Array :
Firestore.instance
.collection('posts')
.orderBy('createdAt', descending: true)
.where("userlist", arrayContains: userId)
.snapshots(),
here is the map stored in firebase
It doesn't really make sense for userlist to be an array here. Firestore doesn't let you query for values of maps inside an array. Just store it as a map. If userlist was just a map of uid/value pairs, you could query it like this using dot notation:
Firestore.instance
.collection('posts')
.orderBy('createdAt', descending: true)
.where('userlist.' + userId, isEqualTo: true)
.snapshots(),
Just adding to Doug Stevenson's answer, I had to use the key isGreaterThan: '' in order to not get an empty array.
Firestore.instance
.collection('posts')
.where('userlist.' + userId, isGreaterThan: '')
.snapshots(),
I don't recommend your way of data model. Because of some limitations as below:
You can only have 20000 fields in a firestore document (including array fields).
You can't assign security rules to each field. Security Rules is a thing that you have to think of.
You can't query them.
So, better I would recommend you to use documents for each user.
I've tried both Doug Stevenson's and Dan James's answers and was getting empty array as a result.
I've finally received the correct result by using the where clause with not equal to ''