1

While I'm using the below query in Firestore, an error is coming:

Code:

query = database.collection("CustomerViews/Data/Post")
  .whereGreaterThanOrEqualTo("postDate", startDate)
  .whereLessThanOrEqualTo("postDate", endDate)
  .orderBy("postViews", Query.Direction.DESCENDING)
  .orderBy("postDate", Query.Direction.DESCENDING) 

Error:

Invalid query. You have an inequality where filter (whereLessThan(), whereGreaterThan(), etc.) on field 'postDate' 
and so you must also have 'postDate' as your first orderBy() field, but your first orderBy() is currently on field
'postViews' instead.
Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
Sabir Syed
  • 422
  • 3
  • 19

3 Answers3

2

The error message is quite explicit about the error. You are using both "whereGreaterThan()" and "whereLessThan()" on the "postDate" field, but you aren't first ordering the results based on that field, hence that error. Please remember, that the order of the method calls in Firestore is very important. To solve this, please change your query to:

query = database.collection("CustomerViews/Data/Post")
  .orderBy("postDate", Query.Direction.DESCENDING)
  .whereGreaterThanOrEqualTo("postDate", startDate)
  .whereLessThanOrEqualTo("postDate", endDate)
  .orderBy("postViews", Query.Direction.DESCENDING)

And right after that, simply create the corresponding index. That's it.


Edit:

According to your first comment:

By using your code data is coming but "postViews" descending is not happening. Only postDate descending is coming.

Yes, the results will be returned descending according to "postDate". And if two or more elements will have the same "postDate", then only those results will be after that ordered descending according to "postViews". This is how Firestore works.

According to your second comment:

I want the "postViews" in descending order in given date ranges.

Cloud Firestore queries can only sort or filter range on a single field. What you are trying to achieve it's not possible, since you are trying to filter on "postDate" and then order on "postViews".

In the official documentation, there is an example on how not to do it:

  • Range filter and first orderBy on different fields

     citiesRef.whereGreaterThan("population", 100000).orderBy("country"); //Invalid
    

According to your last comment:

I got the solution for my problem. I have added the below line before attaching the ArrayList to an adapter.

postArrayList.sortByDescending { it.PostViews  }

Indeed it will work if you download all documents on the client and to the filtering there, but it will cost you one document read for each document you download.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • thanks for your revert. By using your code data is coming but postViews descending is not happening. Only postDate descending is coming. – Sabir Syed Nov 10 '21 at 11:48
  • @Alex-Memo, i want the postViews in descending order in given date ranges. How to get the same. Whether it will be possible with arraylist sorting. Please suggest. – Sabir Syed Nov 10 '21 at 12:51
  • Please check my updated answer. I hope it's clear now. Is it? – Alex Mamo Nov 10 '21 at 13:00
  • I got the solution for my problem. I have added below line before attaching the arraylist to an adapter. ```postArrayList.sortByDescending { it.PostViews }``` – Sabir Syed Nov 10 '21 at 13:04
  • Any how thanks @Alex-Memo for your revert. I'm a greate fan of yours. – Sabir Syed Nov 10 '21 at 13:05
  • Your solution is just sorting the elements on the client. The problem comes when using Queries. Besides that, the question was about queries. Edited again, please check. – Alex Mamo Nov 10 '21 at 13:24
  • Btw, you're very welcome. Sabir. – Alex Mamo Nov 10 '21 at 13:24
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/239083/discussion-between-sabir-syed-and-alex-mamo). – Sabir Syed Nov 10 '21 at 13:25
1

Based on your sample code, you have an inequality wherein postDate should be initialized first before postViews as the error suggested. This is currently a restriction of orderBy() clause wherein your first ordering must be on the same field.

In addition to @Alex's answer, You may check the links below for similar scenarios

Finally, here's a documentation for the limitations of order and limit data with Cloud Firestore.

Robert G
  • 1,583
  • 3
  • 13
0

I got the solution for my problem. I have added below line before attaching the arraylist to an adapter.

postArrayList.sortByDescending { it.PostViews }

Sabir Syed
  • 422
  • 3
  • 19