3

How to implement multiple order by in Android Firestore based on different if conditions?

I want to sort my firestore items based on different fieldvalues like this:

Query query= firestoredb.collection('items').document(docid).orderby('price').orderby('itemcategory').orderby('name**');

But how many orderby will be added is dynamic . It will decide during runtime i.e what user will select from sort options.

So how would I make my Firestore query in android?

Please help me.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
Ram Chhabra
  • 421
  • 8
  • 11

2 Answers2

4

A query like the one you are using in your code:

Query query= firestoredb.collection('items').document(docid).orderby('price').orderby('itemcategory').orderby('name');

Is not possible in Cloud Firestore because firestoredb.collection('items').document(docid) return a DocumentReference object and you cannot call orderBy() method on it. So assuming you want to use a query, the following line of code:

Query query= firestoredb.collection('items').orderby('price').orderby('itemcategory').orderby('name');

Will work perfectly fine. There is no problem in Firestore to order by multiple fields. You can even set the direction passing as the second argument: Direction.ASCENDING or Direction.DESCENDING.

Edit:

According to your comment, you should create an if statement or even better, a switch statement and accordingly to what the user is seleting to create a new query object. So if the user selects only price, then the query should look like this: firestoredb.collection('items').orderby('price'), that's it. See an example below:

Query query;
switch (option) {
    case "price":
        query = firestoredb.collection('items').orderby('price');
        break;
    case "itemcategory":
        query = firestoredb.collection('items').orderby('itemcategory');
        break;
    case "price_itemcategory":
        query = firestoredb.collection('items').orderby('price').orderby('itemcategory');
        break;
    case "name":
        query = firestoredb.collection('items').orderby('name');
        break;
    case "price_name":
        query = firestoredb.collection('items').orderby('price').orderby('name');
        break;
    default:
        query = firestoredb.collection('items'); //No ordering
        break;
Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • Yes , I agree with you that there is no problem in Firestore to order by multiple fields but my question is how I dynamically add or remove my orderby fields based on user input i.e what user will select from order by options? It could be orderby('price') only It could be orderby('itemcategory') and orderby('price') or It could be orderby('name') and orderby('price') – Ram Chhabra Aug 23 '18 at 12:06
  • In this case, please see my updated answer. Is this ok now? – Alex Mamo Aug 23 '18 at 12:20
  • Thank you Its working but making multiple possible combination of cases making it more typical instead of it I have found a another way just like that Query query=firestoredb.collection('items'); if('price') query = query.orderby('price'); if('name') query = query.orderby('name'); if('itemCategory') query = query.orderby('itemCategory'); – Ram Chhabra Aug 29 '18 at 06:46
  • Which is tipically the same thing :) But good to hear that it worked. – Alex Mamo Aug 29 '18 at 08:20
  • I did same but it raises error of "Error: 9 FAILED_PRECONDITION: The query requires an index." help – Onk_r Feb 19 '19 at 06:27
  • how do I create indexing programatically. After exploring about it, it is said that when you need to do dynamic indexing then your model structure is bad. But for above code how to deal with indexing??? – Onk_r Feb 19 '19 at 06:30
  • @Onk_r You need to create an [index](https://stackoverflow.com/questions/50305328/firestore-whereequalto-orderby-and-limit1-not-working) for each case in order to make it work. – Alex Mamo Feb 19 '19 at 07:54
-4
 Query query=firestoredb.collection("items"); 
 if(PRICE.equals("price")) {
      query = query.orderby('price'); 
 }
 if(NAME.equals("name")) {
      query = query.orderby('name'); 
 }
 if("itemCategory"){
      query = query.orderby('itemCategory');
 }
Ram Chhabra
  • 421
  • 8
  • 11
  • 1
    This solution is the same solution as mine but only that you have used an `if statement` rather then a `switch statement`. The main difference is that your code doesn't solve the situaton in which you need to order by two properties, as you original request was. – Alex Mamo Aug 29 '18 at 10:42
  • 1
    Hi @Alex, You are adding an **orderby** in firebase collection and assigning it to **query** object and in each case statement you are replacing the **query** object. Also you are using multiple **orderby** to make a combination i.e for two properties(name,item) there must be 4 possible case statement required similarly for 3 properties(name,item,category) 6 possible case statements will be needed and here In my code I am appending the **orderby** with the previous **query** object and yes my code solve the situation in which I need to order by two properties, as my original request was. – Ram Chhabra Aug 30 '18 at 06:38
  • 1
    So if you say that your original question was to order by two properties and my answer solves your problem, why to accept an answer which contains not even half of a solution? This may confuse future visitors. – Alex Mamo Aug 30 '18 at 10:41