• Skip to primary navigation
  • Skip to main content
  • Skip to primary sidebar

I Like Kill Nerds

The blog of Australian Front End / Aurelia Javascript Developer & brewing aficionado Dwayne Charrington // Aurelia.io Core Team member.

  • Home
  • Aurelia 2
  • Aurelia 1
  • About
  • Aurelia 2 Consulting/Freelance Work

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

Firebase · May 4, 2017

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) {
    console.log(snapshot.val());
});

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;

        returnArr.push(item);
    });

    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) {
    console.log(snapshotToArray(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.

Dwayne

Leave a Reply Cancel reply

24 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
allen joslin
allen joslin
5 years ago

An ES7 one-liner:

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

2
Dwayne
Dwayne
Author
5 years ago

Allen,

That is really nice. Thanks for sharing that!

0
Valery
Valery
5 years ago

Thanks, very useful pattern !

0
Gabriel
Gabriel
5 years ago

Very Thanks.

0
Moshiour Rahman
Moshiour Rahman
5 years ago

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.

0
haytham
haytham
5 years ago

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 !

0
Bobr
Bobr
5 years ago

ES6:
Object.keys(s.val() || {}) .map(k => s.val()[k]);

0
Kevin Cho
Kevin Cho
5 years ago

Thank you for sharing snapshotToArray(snapshot) 🙂

0
Chris
Chris
5 years ago

Great help, thanks

0
DKMin
DKMin
4 years ago

Wow, thanks a lot. Dwayne & allen joslin

0
Philip Sotirov
Philip Sotirov
4 years ago

Hey, thanks for sharing

what do you think about this approach?
https://gist.github.com/fipo/483a07bc741e7f4b470b8bc3e6c7bdac

I prefer to keep the id and use it for the `key=` prop

0
John francis
John francis
4 years ago

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

0
Carlos Guillen
Carlos Guillen
4 years ago

Object.values(snapshot.val()) also does the job

2
Valmir Verbani
Valmir Verbani
4 years ago

I can’t stress how helpful this was. I am finding the documentation on Firebase isn’t the most clear. Thank you for posting this solution!

0
yukti
yukti
4 years ago

hello please tell me how to fetch the resent updated value from firebase and display in map as a marker

0
SeriousGUy888tydhsbf
SeriousGUy888tydhsbf
3 years ago

Thank you for sharing this!

0
GM
GM
3 years ago

I still have no idea why they not returning an array response instead…

0
Nicola
Nicola
3 years ago

Thank you!

0
Sai
Sai
2 years ago

Thanks. This really helped

0
manisha
manisha
1 year ago

its working

0
Miguel Gomez
Miguel Gomez
1 year ago

Thanks a lot! Really helpful!

0
Daniel Perley
Daniel Perley
1 year ago

I need to be able to make an API call from one app and return an array of posts while keeping the default functionality for other apps. Have you any experience with creating a custom url to query data as an array but leaving it as is for default rest url? Would it automatically default to the url of the function?

0
Denise Ysabelle Areza
Denise Ysabelle Areza
6 months ago

how do you extract a specific data from an array

0
trackback
Const is not defined -> Yet standard solutions don’t work - It 工作记录站
29 days ago

[…] If snapshot.docs isn’t available but you can still use snapshot.forEach(), then you can convert the Firebase object to an Array similar to Convert A Firebase Database Snapshot/Collection To An Array In Javascript: […]

0

Primary Sidebar

Popular

  • Thoughts on the Flipper Zero
  • Testing Event Listeners In Jest (Without Using A Library)
  • How To Get The Hash of A File In Node.js
  • Waiting for an Element to Exist With JavaScript
  • How To Paginate An Array In Javascript
  • Reliably waiting for network responses in Playwright
  • How To Get Last 4 Digits of A Credit Card Number in Javascript
  • How to Use Neural DSP Archetype Plugins With the Quad Cortex
  • Neural DSP Reveal Details About the Long-Awaited Quad Cortex Desktop Editor
  • How To Mock uuid In Jest

Recent Comments

  • Kevmeister68 on Start-Ups and Companies That Embrace Work From Anywhere Will Be More Likely to Survive the Coming Recession in 2023
  • kevmeister68 on What Would Get People Back Into the Office?
  • Dwayne on PHP Will Not Die
  • Dwayne on How to Create a Blockchain With TypeScript
  • kevmeister68 on PHP Will Not Die

Copyright © 2023 · Dwayne Charrington · Log in

wpDiscuz