skip to Main Content

I’m in quite a predicament. I created a cloud function that would update the "updated_at" field in a user’s profile, that is triggered every time the user updates some part of their profile. To my horror however, this update (completed via the cloud function), is continuously triggering the cloud function also. So I just had the function complete 1000’s of updates in the last few minutes and my only solution appeared to be to delete the function on the server. So how does one go about updating this field if it triggers itself? Here’s the function that caused the issue:

exports.generateUpdatedAtTest = functions.database.instance("bd-dev")
.ref("/UserData/{uid}/profile")
.onUpdate((snapshot, context) => {
  functions.logger.log("updated_at on ", context.params.uid);
  return snapshot.before.ref.update({"updated_at": new Date()});
});

2

Answers


  1. Chosen as BEST ANSWER

    I figured out that adding this check helped prevent the recursion. Basically once the onUpdate trigger calls itself once more, the before and after updated_at fields would only be the same if the change was generated from the app. So this finally helped.

    // updated_at should only be the same if profile updated in app
      if (before.updated_at !== after.updated_at) {
        console.log("Cancel onUpdate trigger.");
        return null;
      }
    

  2. There is no special flag or signal you can send to stop a function from taking an action that would invoke itself. You must to devise a way to detect if your function should do nothing when invoked, using only the data available at the time of the invocation (especially the existing data in the database). This strategy is going to vary from function to function.

    For your specific case, one possibility is look at the current value of the updated_at field, and decide not to update it again if it’s within some small threshold from the current time.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search