Home > Back-end >  Problem with firebase query orderByChild().equalTo() android kotlin
Problem with firebase query orderByChild().equalTo() android kotlin

Time:11-12

I have a problem. Below in the screenshot, you can see the structure of my database. I need to filter my query regarding two fields: subgroup and time.

I wrote the following code:

private fun readFromDatabase() {
    ref?.orderByChild("time")
        ?.equalTo("12:00 - 13:30")
        ?.orderByChild("subgroup")
        ?.equalTo("first")
        ?.addValueEventListener(object: ValueEventListener {
        override fun onDataChange(snapshot: DataSnapshot) {
            if (snapshot.exists()) {
                val list = ArrayList<Day>()

                for (daySnapshot in snapshot.children) {
                    val day = daySnapshot.getValue(Day::class.java)

                    list.add(day!!)
                }

                adapter.submitList(list)
            }
        }

        override fun onCancelled(error: DatabaseError) {

        }
    })
}

However, I got the error: java.lang.IllegalArgumentException: You can't combine multiple orderBy calls!

Is there any way how I could do it differently?

enter image description here

CodePudding user response:

As the error message states:

java.lang.IllegalArgumentException: You can't combine multiple orderBy calls

There is no way you can combine multiple orderByChild() methods calls in a single query. Firebase Realtime Database only supports queries on a single child property.

To solve this, you might take into consideration, creating a new field that will hold both values. Your node should look like this:

Firebase-root
  |
  --- classRooms
        |
        - 0
          |
          --- time_subgroup: "12:00 - 13:30_first"

So as you can see, the time_subgroup property combines both values that you want to filter on.

But there is a down-site. If you want to order strings, the order is always lexicographically.

So unlike in the Realtime Database, Cloud Firestore allows compound queries. So I recommend you try that. So a query like the one below will work perfectly fine in Cloud Firestore without the need of creating a combined property.

classRoomsRef.whereEqualTo("time", "12:00 - 13:30").whereEqualTo("subgroup", "first")

CodePudding user response:

Like it says, you can't combine multiple orderBy calls. You'll need to filter out the results with only one orderBy.

private fun readFromDatabase() {
    ref?.orderByChild("time")
        ?.equalTo("12:00 - 13:30")
        ?.addValueEventListener(object: ValueEventListener {
        override fun onDataChange(snapshot: DataSnapshot) {

if (snapshot.exists()) {
   val list = snapshot.children.stream()
      .map(snapshot => snapshot.getValue(Day::class.java)
      .filter(day => "first".equals(day.subgroup))
      .map(day => day!!)
      .collect(Collectors.toCollection(ArrayList::new));
  • Related