1

I'm using FirebaseRecyclerAdapter and pass FirebaseRecyclerOptions with some query into constructor. Each item has number of fields including timestamp a and another integer field b. So I want items with older a but less b to be on top of list. It's easy to implement with sqlite, but not so easy with nosql. It seems I need to add some extra field which keeps both fields: String.valueOf(a) + String.valueOf(b) but how to achieve asc / desc properties?

Loading the whole list and sorting in Java is not an option.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
RChugunov
  • 794
  • 2
  • 11
  • 26
  • You seem to already have found how to [filter on multiple properties](http://stackoverflow.com/q/26700924) in the Realtime Database. There is no option to have the database reverse the results, but you can: 1) reverse them client-side, which is *always* an option given that you're already loading all the data over a network connection, 2) store an inverted value in a property in the database and order on that. See [this answer](https://stackoverflow.com/a/46255310) and more from [this list](https://stackoverflow.com/search?q=%5Bfirebase-realtime-database%5D%5Bandroid%5D+descending). – Frank van Puffelen May 01 '20 at 14:18

1 Answers1

0

Unfortunately, Firebase Realtime database does not support queries on multiple properties, supports only queries on a single child property. So, you're correct in guessing that you'll need to create an extra field to keep both fields. So to achieve this, you need to create a new field which in your database should look like this:

Firebase-root
   |
   --- itemId
          |
          --- a: valueOfA
          |
          --- b: valueOfB
          |
          --- a_b: valueOfA_valueOfB

So as you see, the a_b property combines the values that you want to filter on.

Unlike Firebase Realtime database, Cloud Firestore allows compound queries. You should take a look at this. So a query as the one below is allowed in Cloud Firestore without creating a combined property.

itemIdRef.whereEqualTo("a", "valueOfA").whereEqualTo("b", "valueOfB");

When you order strings this is the normal ordering method. A quick fix would be to add two zeros before each second element like this: "1516428687_001", "1516428687_002", "1516428687_012". Now your order will be fine. For more explanations, please see my answer from this post.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • the problem is I actually request all items without equalsTo but with order. In this case if I just concatenate two fields then I won't be able to use ASC/DESC as I mentioned in my question – RChugunov Jan 19 '18 at 15:15
  • Speaking about Firebase Realtime database, yes you can, passing the new `a_b` property to order method like this: `.orderBy("a_b")`. – Alex Mamo Jan 19 '18 at 15:21
  • I thought about it - but in practice it won't work because as I guess internally firebase uses standard strings comparator so the order of three keys will be following `"1516428687_1", "1516428687_12", "1516428687_2"`. But I need `"1516428687_1", "1516428687_2", "1516428687_12"`. Do you have more ideas @alex-mamo? – RChugunov Jan 20 '18 at 06:16
  • When your order strings this is the normal ordering method. A quick fix would be to add two zeros before each second element like this: `"1516428687_001"`, ` "1516428687_002"`, `"1516428687_012"`. Now your order will be fine. For more explanations, please see my answer from [here](https://stackoverflow.com/questions/46647150/how-to-order-the-nodes-in-firebase-console-based-on-key). Is it ok now? – Alex Mamo Jan 20 '18 at 09:46
  • Yes, that works, I implemented this approach, but this workaround is far from straightforward solution. For now it seems firebase has huge lack of API. Can you edit your answer, or just add a reference to that another answer, and I accept it? – RChugunov Jan 21 '18 at 07:06
  • You're right but this how things works when it comes to Firebase Realtime database. Give it a try, use Cloud Firestore for your project, it allows compound queries. And yes, just edited my answer. Thanks! – Alex Mamo Jan 21 '18 at 09:56