Updating Firestore Documents in Parallel Using Promise.all()

Tags: , , ,



This question concerns the Firestore database, but, more generally, it concerns making async requests in parallel.

Simply put, I wish to update multiple Firestore documents as quickly and efficiently as possible by mapping over an array of their document IDs.

the .set() method is async (returning a promise) and so I understand that I can wrap the multiple requests – i.e. the map() – in a Promise.all() function, which will return a single promise once all of the requests have resolved.

However, it is not at all clear to me whether I should await the set() within the map().

Whichever way I write the code (i.e. with or without await), it does not appear to make a difference to speed, but does it, or should it?

What is the correct way to achieve the greatest speed and efficiency in this instance?

    const update_promises = array_of_ids.map(async id => {

      const new_values = {
        new_values_1: "val1",        
        last_update: new Date()
      }      

      return await db.collection("my_collection").doc(id).set(new_values, { merge: true });

      // OR SHOULD IT BE:

      // return db.collection("my_collection").doc(id).set(new_values, { merge: true });
    })

    return await Promise.all(update_promises)

Answer

When get call set(), the SDK is going to immediately pipeline the write request over the a single managed connection. If you want to write a bunch of documents as fast as possible, you should kick them all off, then await the results at the end. You probably don’t want to await each one individually, since you are causing the code to stop for a moment while it waits for the result before the next one can get sent. That said, the performance impact is probably negligible overall, unless you have a lot of work to be done in between each write.

My general rule is to only await an individual promise if its result is needed right away before moving on. Otherwise, collect all the promises together into an array for a single await with Promise.all().



Source: stackoverflow