Mark
Mark

Reputation: 515

Cloud Functions for Firebase OnWrite

I'm looking at the New Cloud Functions for Firebase and it says when doing an OnWrite you should be careful not to save data back to the same Child. (which will fire off the trigger again).

So I'm trying to figure out, how do I set a modification date on a record ?

Upvotes: 18

Views: 16560

Answers (2)

Michael Bleigh
Michael Bleigh

Reputation: 26313

The issue isn't that you can't or shouldn't change the data, but that you need to guard against infinite loops. For instance, setting a timestamp could retrigger the function which would set the timestamp which would retrigger...and so on.

What you can do, however, is guard your code by making sure to mark the state in an idempotent way so the same code doesn't retrigger. For example:

exports.doThing = functions.database.ref('/events/{id}').onWrite(ev => {
  // prevent loops by guarding on data state
  if (ev.data.child('didThingAt').exists()) return;

  // do thing here...

  return ev.data.adminRef.update({
    didThingAt: admin.database.ServerValue.TIMESTAMP
  });
});

Upvotes: 18

Juan Pablo
Juan Pablo

Reputation: 1223

I understand firebase functions provides a better method:

The method is to verify if a previous event exists. If so, do nothing and return else, do you job... Besides you can verify if item is being deleted.

  if (event.data.previous.exists()) {
    return;
  }
  // Exit when the data is deleted.
  if (!event.data.exists()) {
    return;
  }

This is full example from firebase documentation.

exports.makeUppercase = functions.database.ref('/messages/{pushId}/original')
    .onWrite(event => {
      // Only edit data when it is first created.
      if (event.data.previous.exists()) {
        return;
      }
      // Exit when the data is deleted.
      if (!event.data.exists()) {
        return;
      }
// Grab the current value of what was written to the Realtime Database.
const original = event.data.val();
console.log('Uppercasing', event.params.pushId, original);
const uppercase = original.toUpperCase();
// You must return a Promise when performing asynchronous tasks inside a Functions such as
// writing to the Firebase Realtime Database.
// Setting an "uppercase" sibling in the Realtime Database returns a Promise.
return event.data.ref.parent.child('uppercase').set(uppercase);

Upvotes: 5

Related Questions