Nik
Nik

Reputation: 709

Firebase onWrite does not trigger

I am trying to use onWrite for db_uppercaseLog but it does not trigger. When I use onCreate, it does trigger.

db_uppercaseLog listens for new log added to /log/:pushId/original and creates an uppercase version of the log to /log/:pushId/uppercase

onCreate((snapshot,context)=>{...} // works fine
onWrite((snapshot,context)=>{...} // did not work

I have go through the doc & reference. Also have read similar question here on stackoverflow. But I can't relate to my case. This should be a text-book example right?

What am I doing wrong here?


// Take the text parameter passed to this HTTP endpoint and insert it into the
// Realtime Database under the path /log/:pushId/original
// <host>/pushLog?text=
exports.pushLog=functions.https
.onRequest(async(req,res)=>{
  // Grab the text parameter.
  const original = req.query.text;
  // Push the new log into the Realtime Database using the Firebase Admin SDK.
  const snapshot = await admin.database().ref('/log').push({original: original});
  res.status(200).send(
    `<!doctype html><head><title>pushLog</title></head><body>
      <a href="${snapshot.ref.toString()}" target="_blank">${original} was saved</a>
    </body></html>`
  );
});

// Listens for new log added to /log/:pushId/original and creates an
// uppercase version of the log to /log/:pushId/uppercase
exports.db_uppercaseLog=functions.database
.ref('/log/{pushId}/original')
.onWrite((snapshot,context)=>{
  // Grab the current value of what was written to the Realtime Database.
  const original = snapshot.val();
  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 snapshot.ref.parent.child('uppercase').set(uppercase);
});

Upvotes: 0

Views: 257

Answers (1)

samthecodingman
samthecodingman

Reputation: 26171

Your problem stems from that onWrite and onCreate handle data differently and are defined differently to what you have in your question.

onCreate((snapshot,context)=>{...})
onWrite((change,context)=>{...})

In particular, a Change object is a container that holds the properties after and before, representing the state change that triggered the function.

As onWrite is a change handler - it can re-trigger itself into an infinite loop if not moderated. In your code above, this is not an issue but important to note. But your code would be triggered when values are deleted, so decide how you wish to handle that.

// Listens for changes at /log/:pushId/original and creates an
// uppercase version of the log at /log/:pushId/uppercase
exports.db_uppercaseLog=functions.database
.ref('/log/{pushId}/original')
.onWrite((change,context)=>{
  let afterSnapshot = change.after;

  // onWrite is triggered on deletion
  if (!afterSnapshot.exists()) {
    console.log('cancelled: entry deleted');
    return; // do nothing (could also delete /log/:pushId/uppercase?)
  }

  // Grab the new value written to the Realtime Database and modify it.
  const newValue = afterSnapshot.val();
  const uppercase = newValue.toUpperCase();

  // Set "../uppercase" and returns its operation Promise.
  return afterSnapshot.ref.parent.child('uppercase').set(uppercase);
});

Upvotes: 2

Related Questions