Convert A Firebase Database Snapshot/Collection To An Array In Javascript

Last updated: March 8, 2018

Because Firebase is a NoSQL JSON data store, you might have noticed that when you get some data from Firebase that it is an object. If the title wasn’t obvious enough, we are talking about using Firebase Realtime Database in a web application.

Take the following example:

firebase.database().ref('/posts').on('value', function(snapshot) {

Let’s imagine that we have 20 posts in our database. You’ll get back an object containing keys and objects for all of our imaginary posts.

If you’re working with a Javascript framework or library such as Aurelia, then you’ll know that iterating an object opposed to an array is more complicated (especially HTML templating).

So, here is a function I ended up writing which I use quite a lot in my Firebase applications:

function snapshotToArray(snapshot) {
    var returnArr = [];

    snapshot.forEach(function(childSnapshot) {
        var item = childSnapshot.val();
        item.key = childSnapshot.key;


    return returnArr;

I am a big fan of verbose functions, although using the power of modern spec Javascript you can create a more condensed shorthand equivalent of the above function.

To use our newly created function

firebase.database().ref('/posts').on('value', function(snapshot) {

If you are using a transpiler like Babel, writing using TypeScript or targeting evergreen browsers like Chrome and Firefox, a nicer solution is:

const snapshotToArray = snapshot => Object.entries(snapshot).map(e => Object.assign(e[1], { key: e[0] }));

You call our shorthand function the same, but it’s a less verbose and harder to understand one-line function. Special thank you to the commenters below who have proposed their own solutions as well.

Purchase Aurelia for Real World Applications over at Leanpub now




12 thoughts on “Convert A Firebase Database Snapshot/Collection To An Array In Javascript

  1. An ES7 one-liner:

    let arr = Object.entries(snapshot).map(e => Object.assign(e[1], { key: e[0] }));

  2. That key interrupts the loop number, for example if a node only contain 2 child then another extra child ‘key’ is added. that increase the loop number.

  3. did you try it ?

    the problem in the first place is we get object of values…
    so we dont have .forEach … because its unknown object and not array !

  4. I am using similar solution in angular with ionic 3. My issue is this: when I bind my datas to html, I could not get a unique key for each entry.

    I am trying to implement a like/unlike button right on esch entry binded but the key for each entry is my problem.

    For example: adding a delete button on each binded entry. When clicked, it deletes another entry and not the actual post.

    Using navParams works fine but one has to goto post details first.

    How do I get a unique key for each post binded without going to post details first? Any ideas please?

    Posts are binded in timeline.html and logins in timeline.ts and post details are binded in post-details.html and navparams from post-details.ts

Leave a Reply

Your email address will not be published. Required fields are marked *