1

I want to do a query by using orderByChild and also filtering with the key of those child. In this case, my keys and values are both data that works for querying what I want.

My problem is presented when the keys contains numbers, if the keys only have letters, then there is no problem. I'm trying to maintain always letters along the numbers since I read the recommendation in another answer directly from a firebaser.

My json is:

{
  "my_list":{
    "100xyz":{
      "value1": 100,
      "value2": 100,
      "name":"100xyz"
    },
    "200xyz":{
      "value1": 200,
      "value2": 200,
      "name":"200xyz"
    },
    "300xyz":{
      "value1": 300,
      "value2": 300,
      "name":"300xyz"
    },
    "400xyz":{
      "value1": 400,
      "value2": 400,
      "name":"400xyz"
    },
    "500xyz":{
      "value1": 500,
      "value2": 500,
      "name":"500xyz"
    }
  }
}

My code is:

DatabaseReference root = FirebaseDatabase.getInstance().getReference().getRoot();
DatabaseReference list = root.child("my_list");
list.orderByChild("value2").startAt(100, "100xyz").endAt(500, "200xyz").addChildEventListener(new ChildEventListener() {
    @Override
    public void onChildAdded(DataSnapshot dataSnapshot, String s) {
        SomeModel someModel = dataSnapshot.getValue(SomeModel.class);
        Log.d("SOME_MODEL", someModel.getName());
    }
});

The problem is I can see 4 childs in the console:

D/SOME_MODEL: 100xyz
D/SOME_MODEL: 200xyz
D/SOME_MODEL: 300xyz
D/SOME_MODEL: 400xyz

But I should only be seen 2

D/SOME_MODEL: 100xyz
D/SOME_MODEL: 200xyz

I want to emphazise: it does works, as long as the keys don't have numbers.

How can I filter by orderByChild and key at the same time when the keys have numbers?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
cutiko
  • 9,887
  • 3
  • 45
  • 59
  • Since I'm likely the Firebaser that answered in the question you speak about (a link is always appreciated when you refer to another question), I'd love to help. Can you reduce your question to a single JSON with a single corresponding code sample that reproduce the problem? – Frank van Puffelen Aug 11 '17 at 01:51
  • @FrankvanPuffelen sorry for skipping the link, I'm trying to solve this since yesterday, little tired by now. I have applied the editions you have suggested. Please, let me know if there is anything else I can do to improve my question. – cutiko Aug 11 '17 at 02:57
  • Why are you not using `startAt(String value, String key)`? What do you think the `double` value means? – OneCricketeer Aug 11 '17 at 03:02
  • @cricket_007 because my "value2" is a double so is better to look it up that way. To give you more context, I'm trying to do something like GeoFire does "value1" will be my latitude, "value2" my longitude, and the key will be a combination of both. That way I can orderByChild("longitude"), but only in a range of latitude (the key). Do you think the problem is the double? Because the problem is only happening when the keys have numbers. – cutiko Aug 11 '17 at 03:09

1 Answers1

1

You seem to think that passing two arguments to endAt() makes the query end at whichever of the value or key comes first. That is not how queries work in Firebase.

The second argument to endAt() is only used after the query finds nodes that match the first argument.

So when you're passing endAt(500, "200xyz"), the database first filters on nodes with value2 equal to value2 (the first argument). This means it finds this node as the end of the query:

"500xyz":{
  "value1": 500,
  "value2": 500,
  "name":"500xyz"
}

It then uses the key 200xyz (the second argument) to determine whether to include this node or not (technically: where in the list of multiple nodes to end returning). Since the key 200xyz is before 500xyz the query result doesn't include this node, resulting in:

"100xyz":{
  "value1": 100,
  "value2": 100,
  "name":"100xyz"
},
"200xyz":{
  "value1": 200,
  "value2": 200,
  "name":"200xyz"
},
"300xyz":{
  "value1": 300,
  "value2": 300,
  "name":"300xyz"
},
"400xyz":{
  "value1": 400,
  "value2": 400,
  "name":"400xyz"
},

Also see:

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807