0

I am trying to query a Firebase Cloud Firestore asynchronously for each item in an array. My understanding of the async.map function was that it would perform a function on each item in an array, and only fire its callback once all of the items have been processed. However, the callback below gets executed immediately after the first query, and before any results are available. What's the best way to do this?

var db = admin.firestore();

var getData = function (item, doneCallback) {
db.collection('myCollection').doc(item).get()
.then(results => {
    console.log("Callback here");
    return doneCallback({
        "name": results.data().name,
        "id": results.data().id,
        "phone": results.data().phone,
    });            
});
};

async.map(myArray, getData, function (err, results) {
console.log("Finished");
for (var i=0;i<results.length; i+=1){
    console.log(results[i].name);
    console.log(results[i].id);
    console.log(results[i].phone);
}
});
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Feyman81
  • 410
  • 1
  • 4
  • 14

2 Answers2

1

Another alternative that avoids async.js (I personally find callback code hard to read, promises end up being far more uniform):

var db = admin.firestore();

var promises = [];
for (var i = 0; i < myArray.length; i++){
  var promise = db.collection('myCollection').doc(myArray[i]).get()
      .then(results => {
        console.log("Callback here");
        return {
          "name": results.data().name,
          "id": results.data().id,
          "phone": results.data().phone,
        };
      });            
  promises.push(promise);
}

Promise.all(promises).then(results, () => {
  console.log("Finished");
  for (var i = 0; i < results.length; i++){
      console.log(results[i].name);
      console.log(results[i].id);
      console.log(results[i].phone);
  }
});
Gil Gilbert
  • 7,722
  • 3
  • 24
  • 25
0

The code at Question does not return the Promise from getData() call, see Why is value undefined at .then() chained to Promise?

var getData = function(item, doneCallback) {
  // `return` the `Promise` object from the function
  return db.collection('myCollection').doc(item).get()
    .then(results => {
      console.log("Callback here");
      return doneCallback({
        "name": results.data().name,
        "id": results.data().id,
        "phone": results.data().phone,
      });
    });
};
guest271314
  • 1
  • 15
  • 104
  • 177