Trying to order Firestore results in query - flutter

I have a query that I would like to order by a start date and filter by end date.
return FirebaseFirestore.instance
.collection("content")
.where("active", isEqualTo: true)
.where("end", isGreaterThanOrEqualTo: DateTime.now())
.orderBy("start", descending: true)
.snapshots();
Error:
The initial orderBy() field '[[FieldPath([start]), true]][0][0]' has to be the same as the where() field parameter 'FieldPath([end])' when an inequality operator is invoked.

If you include a filter with a range comparison (<, <=, >, >=), your first ordering must be on the same field
https://firebase.google.com/docs/firestore/query-data/order-limit-data#limitations
So you should go with
return FirebaseFirestore.instance
.collection("content")
.where("active", isEqualTo: true)
.where("end", isGreaterThanOrEqualTo: DateTime.now())
.orderBy("end", descending: true)
.orderBy("start", descending:true)
.snapshots();

You are getting the following error:
The initial orderBy() field '[[FieldPath([start]), true]][0][0]' has to be the same as the where() field parameter 'FieldPath([end])' when an inequality operator is invoked.
Because there is no way you can get data from Firestore without first sorting on the end field when using an inequality operator. So you need to reorder the results in your application code. So after calling:
.where("end", isGreaterThanOrEqualTo: DateTime.now())
It's mandatory to call:
.orderBy("end", descending:false)
So your query should look like this:
return FirebaseFirestore.instance
.collection("content")
.where("active", isEqualTo: true)
.where("end", isGreaterThanOrEqualTo: DateTime.now())
.orderBy("end", descending:false)
.orderBy("start", descending:true)
.snapshots();
Don't also forget to create an index in order to make this query work.

Related

Firebase query is showing inaccurate results

Query
I made this query to search the documents based on doorNumber and merchantId which should be present in the merchants list in the document field and also prepared indexing but it's not working and showing that there are 0 customers.
final customersRef = FirebaseFirestore.instance
.collection('customerDB')
.where('merchants', arrayContains: merchantId)
.where('address.doorNumber', isGreaterThanOrEqualTo: searchKey)
.where('address.doorNumber', isLessThan: searchKey + 'z')
.orderBy('address.doorNumber')
.orderBy('name', descending: true)
.limit(limit);
Firebase data model
Changed z to ~ then it works but we can only search by prefix.
final customersRef = FirebaseFirestore.instance
.collection('customerDB')
.where('merchants', arrayContains: merchantId)
.where('address.doorNumber', isGreaterThanOrEqualTo: searchKey)
.where('address.doorNumber', isLessThan: searchKey + '~')
.orderBy('address.doorNumber')
.orderBy('name', descending: true)
.limit(limit);

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

How can I filter from the map in the document?

How can I filter from the map in the document?
my query function;
ref
.where('tag_id', isEqualTo: item)
.where('likes', arrayContains: {
Get.find<AuthController>().getCurrentUser!.uid: true
})
.orderBy('created_date', descending: true)
.orderBy('like_count', descending: true)
.orderBy('comment_count', descending: true)
.limit(max.value)
.get();
I want to filter on 'likes' map. I tried to make an example in the code below, but no data is coming.
map in document
returning null
Your likes is not an array, so array-contains won't work on it.
What you're looking for is :
const uid = Get.find<AuthController>().getCurrentUser!.uid;
ref
.where('tag_id', isEqualTo: item)
.where('likes.$uid', isEqualTo: true)
For more on this dot notation, see the Firebase documentation on updating fields in nested objects.

How to set a not equal to a firestore query

I have this query
querySnapshot = await Firestore.instance
.collection('sellerPost')
.where("expireTime" , isGreaterThan: DateTime.now())
.where("category", isEqualTo: _selectedCategory)
.where("tags",arrayContains:_selectedTag )
.orderBy('expireTime',descending: true)
.limit(10)
.getDocuments();
I would like to query documents with given categories and tags as specified in the where clause, but in. a situation where the user has not selected a tag or category yet, i would like to query everything.
E.g in my mind i though this would work
querySnapshot = await Firestore.instance
.collection('sellerPost')
.where("expireTime" , isGreaterThan: DateTime.now())
.where("category", isEqualTo: "*")
.where("tags",arrayContains:"*" )
.orderBy('expireTime',descending: true)
.limit(10)
.getDocuments();
Is there a way to query with wild cards this way?

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 ''