Lance Samaria
Lance Samaria

Reputation: 19622

Cloud Functions -How to Update Multiple Refs

I have to fetch data at a couple of refs and update at a couple of refs. Everything works fine except for the fourth ref loopArrAtFourthRef that I have to update. It gets it's values from the third via a loop. The problem is the fifthRef finishes before the fourth ref. I'm a Swift dev and I can't get the hang of Promises, they are way to foreign for me.

exports.updateMultipleRefs = functions.https.onCall((data, context) => {

    // ... values from data used in refs

    const fetchFromFirstRef = admin.database()....
    const updateAtSecondRef = admin.database()....
    const runTransactionAtSecondRef = admin.database()....
    const fetchArrDataFromThirdRef = admin.database()....
    const loopArrAtFourthRef = admin.database()....
    const updateFifthRef = admin.database()....

    var arr = [];
    var promises = [];

    var val_1 = 0;
    var val_2 = 0;

    return fetchFromFirstRef
        .once('value')
        .then((snapshot) => {

        if (snapshot.exists()) {

            snapshot.forEach((childSnapshot) => {
                // val_1 += data from each childSnapshot
            });

            return updateAtSecondRef.update({ "val_1":val_1 }).then(()=> {
                return runTransactionAtSecondRef.set(admin.database.ServerValue.increment(1));

            }).then(() => {

                return fetchArrDataFromThirdRef
                    .once('value')
                    .then((snapshot) => {

                    if (snapshot.exists()) {

                        snapshot.forEach((childSnapshot) => {

                            var gameId = childSnapshot.key;
                            arr.push(gameId);
                        });

                    } else {
                        return null;
                    }
                });

            }).then(() => {

                // this is where I'm having the problem, the fifth ref finishes before this does
                for (var i = 0; i < arr.length; i++) {

                    var gameId = arr[i];

                    var promiseRef = loopArrAtFourthRef.child(gameId);

                    promises.push(promiseRef.once('value').then((snap) => {

                        snap.forEach((child) => {
                            // val_2 += data from each child
                        });
                    }));

                    return Promise.all(promises);
                }

            }).then(() => {

                return updateFifthRef.update({ "val_2": val_2 });
            });

        } else {
            return null;
        }
    })
    .catch((error) => {
        console.log('error', error);
        return null;
    });
});

Upvotes: 0

Views: 113

Answers (1)

Lance Samaria
Lance Samaria

Reputation: 19622

Following this answer and this blog I just had to create an array of Promises and run Promise.all() after the outer for-loop finished:

for (var i = 0; i < arr.length; i++) {

    var gameId = arr[i];

    var promiseRef = loopArrAtFourthRef.child(gameId);

    promises.push(promiseRef.once('value').then((snap) => {

        snap.forEach((child) => {
            // val_2 += data from each child
        });
    }));
}

return Promise.all(promises);

Upvotes: 1

Related Questions