2

I want to have an updatedAt field in my pizza document that should be updated every time there's an update happening in this particular document. I think the best place to handle this is in an onUpdate trigger:

exports.onUpdatePizza = functions.firestore
  .document('pizzas/{pizzaId}')
  .onUpdate(async (change, context) => {
    return change.after.ref.update({ updatedAt: new Date() });
});

However, the above code will fall into an infinite loop. How can I implement this without the undesired side effect?

Yulian
  • 6,262
  • 10
  • 65
  • 92

3 Answers3

1

There is a good explanation there https://medium.com/@krngd2/prevent-infinity-loop-in-firebase-cloud-functions-ea8083afbd35

MichelDelpech
  • 853
  • 8
  • 36
  • 1
    This would be a good answer if you cite or paraphrase the relevant information from the post. That way its not reliant on a link. – giraffesyo Nov 30 '18 at 14:02
1

Add this inside the function:

// simply input data
const after: any = change.after.exists ? change.after.data() : null;
const before: any = change.before.exists ? change.before.data() : null;

const canUpdate = () => {
    // if Update Trigger
    if (before.updatedAt && after.updatedAt) {
        if (after.updatedAt._seconds !== before.updatedAt._seconds) {
            return false;
        }
    }
    // if Create Trigger <--- assuming you use it
    if (!before.createdAt && after.createdAt) {
        return false;
    }
    return true;
}

if (canUpdate()) {
   // update code here
}

Here is my code for universal updates: https://stackoverflow.com/a/60963531/271450

Jonathan
  • 3,893
  • 5
  • 46
  • 77
0

In your function, check to see if the update date is within some threshhold of the current time before updating it again. This will defend against unwanted writes, but the downside is that the update time may lag by that threshold, if there are very frequent updates.

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441