0

I have a Firebase Realtime database function running. The problem is that the foreach loop executes after the return return ref.child("/leaderboard").set(updates); I know i have to do something with Promise() ? But not sure how. Any ideas.

const functions = require('firebase-functions');
const admin = require('firebase-admin');

admin.initializeApp();

// Checks the weekly scores and creates a leaderboard entry of the top 3
exports.insertLeaderboard = functions.database.ref('/challenges/weekly/{weeklyId}/scores/{userId}')
    .onWrite(async (change) => {

        const ref = change.after.ref.parent.parent; // reference to the parent
        const leaderboardItems = ref.child("scores").orderByChild('score').limitToLast(3);
        const snapshot = await leaderboardItems.once('value');
        var updates = snapshot.val();

        snapshot.forEach(async element => {
            const playerRef = admin.database().ref("players/" + element.key + "/playerProfile");
            await playerRef.once('value', (result) => {

                if (result.exists) {
                    console.log("Found Element:" + result.key);
                    updates[element.key]["name"] = result.child("DisplayName").val();
                } else {
                    console.log("NOT Found Element:" + element.key);
                }
            });
        });

        console.log("Doing Final Write");

        return ref.child("/leaderboard").set(updates);
    });
Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
Bigboer
  • 41
  • 1
  • 7
    async does not work the way you would expect with a forEach loop callback function. I suggest reading: https://stackoverflow.com/questions/37576685/using-async-await-with-a-foreach-loop – Doug Stevenson Nov 17 '20 at 16:32
  • 5
    Does this answer your question? [Using async/await with a forEach loop](https://stackoverflow.com/questions/37576685/using-async-await-with-a-foreach-loop) – Soni Sol Nov 18 '20 at 17:18

1 Answers1

0

Yes I solved this by following the steps in this answer by Bergi

async function printFiles () {
  const files = await getFilePaths();

  await Promise.all(files.map(async (file) => {
    const contents = await fs.readFile(file, 'utf8');
    console.log(contents)
  }));
}

Like this!

var data_snap_arr = [];
snapshot.forEach(child_Snapshot => {
    var stuff = child_Snapshot.val();
        stuff.key = child_Snapshot.key;
        data_snap_arr.push(stuff);
    });

    await Promise.all(data_snap_arr.map(handleSnapshot)).then(result => {
    const finalData = {};
    for (var i = 0; i < result.length; i++) {
        // process data here - data returned as array object
    }
    return ref.child("/leaderboard").set(finalData);
});
Henry Ecker
  • 34,399
  • 18
  • 41
  • 57
Bigboer
  • 41
  • 1