Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firebase Database Snapshot ForEach Async Await

async/await doesn't seem to work with firebase forEach. This code runs console.log for the first child of the snapshot and then just hangs. Is this a bug or am I missing something?

main()
async function main() {
  const snap = await root.ref('somepath')
    .once('value')

  snap.forEach(async val => {
    await console.log(val.key)

  })
}
like image 534
prozac Avatar asked Aug 09 '17 16:08

prozac


2 Answers

It's an unintentional consequence of a feature, sometimes knows as a bug. From the firebase documentation: Firebase documentation

an async function always returns a Promise. And a promise is true-y value:

!!Promise.resolve===true.

As a workaround, try this solution:

main()
async function main() {
  const snap = await root.ref('somepath')
    .once('value')

  snap.forEach(function wrapper(){async val => {
    await console.log(val.key)
  }})

It won't wait for the promise to complete before moving to the next snapshot though. That would require a bit more code, but that may not be what you need anyways.

like image 77
Karamell Avatar answered Oct 31 '22 07:10

Karamell


I use something like this:

import * as admin from "firebase-admin";

type FunctionOnDataSnapshot = (childSnapshot: admin.database.DataSnapshot) => Promise<any>;
export const asyncForEach = async (dataSnapshot: admin.database.DataSnapshot, childFunction: FunctionOnDataSnapshot) => {
    const toWait = [];
    dataSnapshot.forEach(childSnapshot => {
        toWait.push(childFunction((childSnapshot)));
    });
    await Promise.all(toWait);
};
like image 5
Artur Owczarek Avatar answered Oct 31 '22 08:10

Artur Owczarek