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
/* code
{
"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 doesn’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 => {
return 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
})
Hope this helps!
If you want to clear the Google Professional Cloud Architect certification exam then you can join Google Cloud Training.