Firebase Query Double Nested

The Firebase API only allows you to filter children one level deep (or with a known path) with its orderByChild and equalTo methods.

So without modifying/expanding your current data structure that just leaves the option to retrieve all data and filter it client-side:

var ref = firebase.database().ref('Users');
ref.once('value', function(snapshot) {
    snapshot.forEach(function(userSnapshot) {
        var blogs = userSnapshot.val().blogs;
        var daBlog = blogs['efg'];
    });
});

This is of course highly inefficient and won't scale when you have a non-trivial number of users/blogs.

So the common solution to that is to a so-called index to your tree that maps the key that you are looking for to the path where it resides:

{Blogs:
     "abc": "1234567",
     "zyx": "1234567",
     "efg": "7654321",
     "hij": "7654321"
}

Then you can quickly access the blog using:

var ref = firebase.database().ref();
ref.child('Blogs/efg').once('value', function(snapshot) {
    var user = snapshot.val();
    ref.child('Blogs/'+user+'/blogs').once('value', function(blogSnapshot) {
        var daBlog = blogSnapshot.val();
    });
});

You might also want to reconsider if you can restructure your data to better fit your use-case and Firebase's limitations. They have some good documentation on structuring your data, but the most important one for people new to NoSQL/hierarchical databases seems to be "avoid building nests".

Also see my answer on Firebase query if child of child contains a value for a good example. I'd also recommend reading about many-to-many relationships in Firebase, and this article on general NoSQL data modeling.


Given your current data structure you can retrieve the User that contains the blog post you are looking for.

const db = firebase.database()
const usersRef = db.ref('users')
const query = usersRef.orderByChild('blogs/efg').limitToLast(1)
query.once('value').then((ss) => {
  console.log(ss.val()) //=> { '7654321': { blogs: {...}}}
})

You need to use limitToLast since Objects are sorted last when using orderByChild docs.