gemboly
gemboly

Reputation: 63

Query on a nested value in children with Firebase Realtime Database where keys are random

I am having an issue querying on nested data from Firebase Realtime Database.

Given the following example data structure:

"crossing":
        "1346":
            "data1": "value"
            "data2": "value"
            "projectName": "PN-1"
        "1562":
            "data1": "value"
            "data2": "value"
            "projectName": "PN-1"
        "1933":
            "data1": "value"
            "data2": "value"
            "projectName": "PN-2"

Let us assume that this collection will have hundreds of children. Also, the ID is random and unknown before the execution time of the query. Every crossing has several other values as you can see in the picture.

At first, I had to list all the crossings whose key starts with the given value. So, for example, if I search for '1', I would like to get all the crossings in this simple example.

This code snippet solves this problem. Although, I am still not sure if this is the best way to achieve this.

firebase
  .database()
  .ref("crossing")
  .orderByKey()
  .startAt(self.searchedKey)
  .endAt(self.searchedKey + "\uf8ff")
  .once("value", function(snapshot) {
    if (snapshot.val()) {
      console.log(snapshot.val());
    }
  });

My main problem is, that now I have to list all the crossings whose projectName value starts with the given value.

However, I cannot compose the proper query for that. I cannot use the .orderByChild() function, since the children keys (the IDs), are unknown.

I cannot afford to query all the crossings from the collection and iterate over all the elements on the frontend side since later this object will be huge with lots of crossings. As I see some kind of order is still a must.

Upvotes: 2

Views: 1300

Answers (1)

Frank van Puffelen
Frank van Puffelen

Reputation: 598951

Firebase Realtime Database can only order/filter on one value from each child node. That can either be the key of each nodes (orderByKey()), its value (orderByValue()), or the value of a single property at a known path under each node (orderByChild("path/to/property")). You can use any of these, but only of of them for any query.

If you want to filter on multiple properties (as an AND) it often is possible to combine the values you want to filter on into a single (synthetic) property. For example, you could (also) add the key of each node in a property and combine it with the project name into: "projectName_key": "PN-1_ 1346" and then order/filter on that property.

For a longer example of this and other approaches, see my answer here: Query based on multiple where clauses in Firebase

Upvotes: 1

Related Questions