Maya
Maya

Reputation: 369

Running concurrent firebase requests using promises

I am trying to execute number of Firebase Cloud Storage queries concurrently using Promise.all() :

exports.onNewOrder = 
functions.database.ref('/orders/{orderId}').onCreate(event => {  
    const data = event.val();
    const orderedBy = data.ordered_by;
    const creations = data.creations;

    var promises = []
    for (var entry of creations.entries()) {
        var key = entry[0], value = entry[1];
        var creationPromise = admin.database().ref("creations/"+ key);
        creationPromise.once("value")
        .then((crSnapshot)=>{
            const crName = crSnapshot.val().name;
            const created = crSnapshot.val().created;
            return "crName+'\n'+created”;
        }).catch((error) => {
            console.log("creation details error : "+ error);
        });
        promises.push(creationPromise);
    }

    const userPromise = admin.database().ref("users/"+ orderedBy);
    userPromise.once("value")
    .then((snapshot) => {
        var name = snapshot.val().name;
        var email = snapshot.val().email;
        const userDetails = name+'\n'+email;
        return userDetails; 
    }).catch((error) => {
        console.log("user details error :"+ error);
    });

    promises.push(userPromise);

    return Promise.all(promises).then(results => {
        console.log("results: " + results)
        return true;
    }).catch((error) => {
        console.log("sendMail failed : "+ error);
    });
});

I am expecting to see complete query result for every executed promise, however I am getting the following instead:

results:

https://....firebaseio.com/creations/cr_1bfd5f16212f44c792a2cbe3e9c6e4cc
https://....firebaseio.com/creations/cr_343c363c2a214487ba8cb7101653f6af
https://....firebaseio.com/creations/cr_e3f7a0bafd1542ac898d96e86155b94e
https://....firebaseio.com/users/us_5e4c28e18e63454c861caa5c4fe6a6f0

Am I missing something?

Upvotes: 0

Views: 178

Answers (1)

Renaud Tarnec
Renaud Tarnec

Reputation: 83058

The following should do the trick.

As detailed here:

The Promise.all(iterable) method returns a single Promise that resolves when all of the promises in the iterable argument have resolved or when the iterable argument contains no promises. It rejects with the reason of the first promise that rejects.

Therefore you need to add some promises to the promises array.

The once() method does return a promise, as explained here in the doc.

exports.onNewOrder = 
functions.database.ref('/orders/{orderId}').onCreate(event => {  
    const data = event.val();
    const orderedBy = data.ordered_by;
    const creations = data.creations;

    const promises = []

    for (var entry of creations.entries()) {
        var key = entry[0];
        var creationPromise = admin.database().ref("creations/"+ key).once("value");
        promises.push(creationPromise);
    }

    const userPromise = admin.database().ref("users/"+ orderedBy).once("value");
    promises.push(userPromise);

    return Promise.all(promises)
    .then(results => {
        console.log("results: " + results);
        return true;
        //actually here you will probably do something else than just write the results to the console. 
        //In this case you should return a promise (instead of true).
    }).catch((error) => {
        console.log("sendMail failed : "+ error);
        return false;
    });

});

Upvotes: 2

Related Questions