Trying to order Firestore results in query

Viewed 1092

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.

2 Answers

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