7

From everything I have read, it doesn't seem possible to query a multilevel value. My data structure looks like the following:

{
"dinosaurs": {
    "bruhathkayosaurus": {
        "meta":{
            "addedBy":"John",
            "addedDate":"02021987"
        },
        "appeared": -70000000,
        "height": 25
    },
    "lambeosaurus": {
        "meta":{
            "addedBy":"Peter",
            "addedDate":"12041987"
        },
        "appeared": -76000000,
        "height": 2.1
    }
}
}

Without knowing the key name of the dinosaurs, is there anyway to query the meta node retrieving only items added by John.

In JS Something like:

    var ref = new Firebase('test.firebaseio.com/dinosaurs');
    ref.orderByChild("meta/addedBy")
    .equalTo('Peter')
    .on("child_added", function(snapshot) {
        console.log(snapshot);
    });

There are hacky solutions but none are scaleable, should I just flatten this data?

Edit:

I need a code review... would this be an acceptable solution?

    var ref = new Firebase('test.firebaseio.com/dinosaurs');
    ref.orderByChild("meta")
    .on('child_added',function(snap1){
        snap1.ref().orderByChild("addedBy")
        .equalTo("Peter")
        .on('child_added', function(snap2) {
           console.log(snap2.val());
        })
    });
dmo
  • 5,102
  • 3
  • 25
  • 28
  • 1
    Be careful: when you have an `on`, you should always consider when the corresponding `off` happens. For top-level `on`s that can be "when the page/app is closed", but your `on` in the `child_added` callback will result in a build-up of listeners over time. The common way to solve this is by using `once` in the loop, but this often also leads to suboptimal performance. – Frank van Puffelen May 11 '15 at 17:17
  • 2
    Also see: http://stackoverflow.com/questions/30151012/is-there-a-way-in-angularfire-to-query-for-matching-and-condition – Frank van Puffelen May 11 '15 at 17:27

1 Answers1

6

Edit Jan 2016: Since this answer, Firebase has Deep Queries so you can query deeper than 1 level.

Queries can only be 1 level deep. There are a number of solutions but flattening your data and linking/referencing is an option.

In the example above you could create another node that links the user names (parent) to the dinosaurs (children) they added. Then John node can be read and immediately know which dinosaurs he added. Then be able to access other relevant data about that dino; date added, appeared,height etc.

users
  John
     bruhathkayosaurus
     Styracosaurus
     Lambeosaurus
     Spinosaurus
  Peter
     Lambeosaurus
     Seismosaurus

You will probably want to use uid's instead of names but you get the idea.

Also, it's not clear why there is a meta node in the example listed so it could be flattened thusly:

"dinosaurs": {
    "bruhathkayosaurus": {
       "addedBy":"John"
       "addedDate":"02021987"
       "appeared": -70000000
       "height": 25
    }, 
Jay
  • 34,438
  • 18
  • 52
  • 81