How to handle Firebase Cloud Functions infinite loops?

Viewed 527

I have a Firebase Cloud functions which is triggered by an update to some data in a Firebase Realtime Database. When the data is updated, I want to read the data, perform some calculations on that data, and then save the results of the calculations back to the Realtime Database. It looks like this:

exports.onUpdate = functions.database.ref("/some/path").onUpdate((change) => {
    const values = change.after.val();
    const newValues = performCalculations(value);
    return change.after.ref.update(newValues);
});

My concern is that this may create an indefinite loop of updates. I saw a note on the Cloud Firestore Triggers that says:

"Any time you write to the same document that triggered a function, you are at risk of creating an infinite loop. Use caution and ensure that you safely exit the function when no change is needed."

So my first question is: Does this same problem apply to the Firebase Realtime Database?

If it does, what is the best way to prevent the infinite looping? Should I be comparing before/after snapshots, the key/value pairs, etc.?

My idea so far:

exports.onUpdate = functions.database.ref("/some/path").onUpdate((change) => {

    // Get old values
    const beforeValues = change.before.val();

    // Get current values
    const afterValues = change.after.val();

    // Something like this???
    if (beforeValues === afterValues) return null;
    
    const newValues = performCalculations(afterValues);
    return change.after.ref.update(newValues);
});

Thanks

1 Answers

Does this same problem apply to the Firebase Realtime Database?

Yes, the chance of infinite loops occurs whenever you write back to the same location that triggered your Cloud Function to run, no matter what trigger type was used.

To prevent an infinite loop, you have to detect its condition in the code. You can:

  • either flag the node/document after processing it by writing a value into it, and check for that flag at the start of the Cloud Function.
  • or you can detect whether the Cloud Function code made any effective change/improvement to the data, and not write it back to the database when there was no change/improvement.

Either of these can work, and which one to use depends on your use-case. Your if (beforeValues === afterValues) return null is a form of the second approach, and can indeed work - but that depends on details about the data that you haven't shared.

Related