Challenges with async cloud function

Hi FFpeople!

Cloud functions sure are tricky! In particular, I'm struggling with this async function that is run from CLI. The purpose of this function is to occasionally recalculate rating summaries (totals and counts) per place by counting & summing the individual ratings documents. This is needed occasionally to clean up data from testing or when a user account is deleted.

I try to use await Promise.all to make sure the first batch of ratings docs has been collected before moving forward, but based on the error below, something isn't right. I think it might be proceeding before it has all the promises but I'm not sure what to do next.

// RATINGSUPDATE FUNCTION
// https function to recalculate ratings summaries for each place based on individual ratings documents
exports.ratingsupdate = onRequest({region:"australia-southeast1"}, async (req, res) => {
  const ratingsCollection = getFirestore().collection("ratings");
  const placesCollection = getFirestore().collection("places02");
  //get ratings docs
  const ratingsSnapshot = await ratingsCollection.get();
  var ratingsSnapshotCount = 0;
  var promises = [];
  var docRef;

  //for each rating doc
  ratingsSnapshot.forEach(ratingDoc => {
    ratingsSnapshotCount++;
    placeRef = ratingDoc.data().placeref;
    logger.log('placeRef:', placeRef),
    docRef = getFirestore().doc(placeRef);
    promises.push(docRef.get());
   });
  
  //wait until all promises done
  await Promise.all(promises);
  logger.log('got', ratingsSnapshotCount, 'ratings');
  logger.log('placesSnapshot is:', promises);

  //set variables for places loop
  var placesSnapshotCount = 0;
  var placeRef = 0;
  var placeName;
  
  // for each place doc that was referenced in ratings
  promises.forEach(placeDoc => {
    placesSnapshotCount++;
    logger.log('got doc:', placeDoc); // from error, doesnt look right..
    placeName = placeDoc.data().name;
    logger.log('got place name:', placeName);
    // to do: write code to increment rating summary counts then push to array of pending place collection updates
   });
  // to do: write code to update places collection with recalculated rating summaries
  logger.log('got', placesSnapshotCount, 'places with ratings');
  res.json({result: Got ${ratingsSnapshotCount} ratings ending in ${placeRef}});
});

Here's the error I see in CLI emulator:

i  functions: Beginning execution of "australia-southeast1-ratingsupdate"
>  {"severity":"INFO","message":"placeRef: /places02/place1"}
>  {"severity":"INFO","message":"placeRef: /places02/place2"}
>  {"severity":"INFO","message":"got 2 ratings"}
>  {"severity":"INFO","message":"placesSnapshot is: [\n  Promise {\n    QueryDocumentSnapshot {\n      _fieldsProto: [Object],\n      _ref: [DocumentReference],\n      _serializer: [Serializer],\n      _readTime: [Timestamp],\n      _createTime: [Timestamp],\n      _updateTime: [Timestamp]\n    }\n  },\n  Promise {\n    QueryDocumentSnapshot {\n      _fieldsProto: [Object],\n      _ref: [DocumentReference],\n      _serializer: [Serializer],\n      _readTime: [Timestamp],\n      _createTime: [Timestamp],\n      _updateTime: [Timestamp]\n    }\n  }\n]"}
>  {"severity":"INFO","message":"got doc: Promise {\n  QueryDocumentSnapshot {\n    _fieldsProto: { datetime: [Object], name: [Object], latlng: [Object] },\n    _ref: DocumentReference {\n      _firestore: [Firestore],\n      _path: [ResourcePath],\n      _converter: [Object]\n    },\n    _serializer: Serializer {\n      createReference: [Function (anonymous)],\n      createInteger: [Function (anonymous)],\n      allowUndefined: false\n    },\n    _readTime: Timestamp { _seconds: 1695628812, _nanoseconds: 191204000 },\n    _createTime: Timestamp { _seconds: 1695628239, _nanoseconds: 829105000 },\n    _updateTime: Timestamp { _seconds: 1695628239, _nanoseconds: 829105000 }\n  }\n}"}
โš   functions: TypeError: placeDoc.data is not a function
    at /Users/jamesmay/Developer/ppstaging/functions/index.js:289:26
    at Array.forEach (<anonymous>)
    at /Users/jamesmay/Developer/ppstaging/functions/index.js:286:12
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async runFunction (/usr/local/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:506:9)
    at async runHTTPS (/usr/local/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:531:5)
    at async /usr/local/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:694:21
โš   Your function was killed because it raised an unhandled error.
i  Request to function failed: Error: socket hang up

1
2 replies