How To Query Arrays of Data in Firebase

How To Retrieve Some Values From A Firebase Object But Not ALL The Values

Say you’re building an app where you can watch curated playlists of videos and your Firebase data looks like this:

// Firebase doesn't support arrays, so EVERYTHING is stored
// using object structure
{
"playlists": {
"09ad08afd": {
"videos": {
"1asdf" : "23423lkj234",
"werv2" : "20982lkjbba"
}
},
"76asdfd0f": {
"videos": {
"345s1" : "adbasdlkj234",
"basr2" : "909ads0kjbba"
}
}
},
"videos": {
"23423lkj234": [some url],
"20982lkjbba": [some url],
...hundreds more,
"909ads0kjbba": [some url],
"adbasdlkj234": [some url
}
}

So you have two ‘tables’. One is an object that consists of playlists with unique keys, and each playlist has a property called “videos” which is an object that consists of key:value pairs of uniques:video-ids.

Now, say you wanted to load a playlist. Because Firebase doesn’t support querying by passing in an array, there’s no way to do something like this to get all the video data that you need:

databaseRef
.child('videos')
.children(["23423lkj234", "20982lkjbba"])
.on('value', snapshot => snapshot.val())

Retrieving all the videos and then filtering client-side is out as well, because that request is potentially unbounded. What’s the most efficient way to retrieve a subsection of the object by key?

I don’t know if this is THE best way, but a cleaner way to do this, and one that does’t require an external library of any sort, is this:

const videosToFetch = ["23423lkj234", "20982lkjbba"]
// Map the Firebase promises into an array
const videoPromises = videosToFetch.map(id => {
databaseRef.child('videos').child(id).on('value', s => s)
})
// Wait for all the async requests mapped into 
// the array to complete
Promise.all(videoPromises)
.then(videos => {
// do something with the data
})
.catch(err => {
// handle error
})

Should your request exceed more than a handful, I recommend using something like Bluebird to do this concurrently without exhausting system resources.