4

I'm using firebase on my android app. I need help to find an issue to my trouble. I want to do a request like this: I was using the oderbyChild("date") to oder my data from the nearest date to the farest by doing this.

MyApplication.backend.child(urls).orderByChild("value").addValueEventListener(new ValueEventListener() {
}

now i want to this select all where the activity value is done and order theme by my date value. i have write this :

MyApplication.backend.child(urls).orderByChild("task").equalTo("done").addValueEventListener(new ValueEventListener(){
}

My problem is that it's not possible to do 2 two orderByChild on the same fireBase query. How can i fix this ? please need help.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Lloyd fairuz
  • 63
  • 1
  • 1
  • 6

2 Answers2

2

Assuming your data looks like this

activities
  -JKjasjiji
    date:   20151129
    is_done: false
  -Ykkjaso23
    date:   20151128
    is_done: true
  -Jkaisjiij
    date:   20151127
    is_done: false

There are a few ways to go about this.

1) query for all activities where is_done: true then sort the results in code. This could be very inefficient depending on data set size. Sorting 1 Million in code would be bad.

2) Store the done activities in another node

activities
  -JKjasjiji
    date:   20151129
  -Jkaisjiij
    date:   20151127

done_activities
  -Ykkjaso23
    date:   20151128

3) Store the data in a format that will enable an 'and' type query

activities
  -JKjasjiji
    done_and_date:   false_20151129
  -Ykkjaso23
    done_and_date:   true_20151128
  -Jkaisjiij
    done_and_date:   false_20151127

Then user .startAt and .endAt...

ref.orderByKey().startAt("true_20151128").endAt("true_20151129")

Would give return all activities that are done between the two specified dates.

Jay
  • 34,438
  • 18
  • 52
  • 81
2

Structuring your data can simplify your queries.

@Jay's answer is great. Here's another way to crack this nut, with the Bolt compiler.

Let's say you're building an expense reporting app, and your data structure goes as follows:

type User {
  name: String;
  uid: String;
}

type Expense {
  id: String;
  amount: Number;
  uid: uid;
  year: Number;
}

path /users/$uid is User;
path /expenses/$expense_id is Expense;

Now let's say you want to get all of the expenses by user 1 that happened in 2014. If this were SQL you could say:

SELECT * 
FROM Expenses
WHERE uid == "1" AND year == 2014 

With the Firebase SDK you would like to do something like this:

ref.child('expenses')
   .orderByChild('uid')
   .equalTo('1')
   .orderByChild('year')
   .equalTo('2014');

But, that's not possible. So what are we to do? Re-structure our data to fit this kind of query.

Rather than store all the expenses under the /expenses location, we can create an index for year with /expenses/year. This would look like:

path /expenses/$year/$expense_id is Expense

Now the query we wanted to do above can be acheived with:

ref.child('2014')
   .orderByChild('uid')
   .equalTo('1');

The structure you choose for your data will allow you to get the data as you need. You may find that you need to duplicate your data to do this. This is okay. And if you need to keep your data consistent across multiple locations, you can use client-side fanout.

David East
  • 31,526
  • 6
  • 67
  • 82