will this google cloud function cause an infinite loop on firestore trigger?

Viewed 262

I have a cloud function that listens to updates to a path in firestore

export const onUserWrite = functions.firestore.document('/path/path').onWrite(async (change) => {
  if (!change.after.exists) {
    return;
  }
  await change.after.ref.update({somedata:'data'});

  return true;
}); 

I think this will cause an infinite loop because, this code await change.after.ref.update({somedata:'data'}); should trigger the function again, thus causing an infinite loop.

if so why wouldn't the documentation mention this?

1 Answers

It does appear that this specific function will result in an infinite loop. Since it is listening for any writes in Firestore, it will execute itself again when the await statement updates the current document using the ref (DocumentReference) property of the change parameter (which is a DocumentSnapshot).

The Firebase Functions repository does include similar sample functions, and a way to deal with potential infinite loops is to implement checks before updating Firestore. This avoids infinite recursive calls to the same function. For the sample function I linked, when a new change is detected, the document will be updated and this specific function avoids infinite recursive calls by checking first for a document property to be set to true.

exports.moderator = 
functions.database.ref('/messages/{messageId}').onWrite((change) => {
  const message = change.after.val();
    //If document is sanitized, skip the function
  if (message && !message.sanitized) {
    //...
    return change.after.ref.update({
      text: moderatedMessage,
      sanitized: true,
      moderated: message.text !== moderatedMessage,
    });
    //Sanitized the document, when this function runs again due to this update, it will be skipped
  }
  return null;
});

You can also check this related question for different approaches to take.

Related