1

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)
Alex Webster
  • 707
  • 1
  • 6
  • 21
  • Highly recommend checking out this for a comparison of the performance of various methods: https://stackoverflow.com/q/58897274/209103 – Frank van Puffelen Aug 14 '20 at 22:39
  • Thanks that is enlightening. If you are using an inline arrow function here, ```async function testParallelIndividualWrites(datas) { await Promise.all(datas.map((data) => collection.add(data)));} ``` I guess you are returning, but not awaiting, the add() method, per @Doug Stevenson's answer? – Alex Webster Aug 14 '20 at 23:41
  • `Promise.all()` resolves when all promises are done, but they can run in parallel. – Frank van Puffelen Aug 15 '20 at 00:13

1 Answers1

1

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().

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441