Reputation:
I am writing my very first Cloud Function which replaces the word "happy" with a smile.
const functions = require("firebase-functions");
const admin = require('firebase-admin');
admin.initializeApp();
exports.emojify = functions.database.ref("/messages/{pushId}/text").onWrite((change, context) => {
const original = change.before.val();
const emojified = emojifyText(original);
return admin.database().ref().set(emojified);
});
function emojifyText(text) {
let t = text;
t = t.replace(/\b(H|h)appy\b/ig, "😀");
console.log("Result:", t);
return t;
};
I found out I can test before deploying by running firebase functions:shell
and doing like this:
firebase > emojify({ before: "Happy!" })
'Successfully invoked function.'
firebase > info: User function triggered, starting execution
info: Result: 😀!
info: Execution took 2949 ms, user function completed successfully
It works. However, when testing with my Android app, the logs of my function will show:
TypeError: Cannot read property 'replace' of null
at emojifyText (/user_code/index.js:15:13)
at exports.emojify.functions.database.ref.onWrite (/user_code/index.js:8:23)
at Object.<anonymous> (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:112:27)
at next (native)
at /user_code/node_modules/firebase-functions/lib/cloud-functions.js:28:71
at __awaiter (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:24:12)
at cloudFunction (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:82:36)
at /var/tmp/worker/worker.js:716:24
at process._tickDomainCallback (internal/process/next_tick.js:135:7)
I don't understand.
After some new attempts, my code is the following:
const functions = require("firebase-functions");
const admin = require('firebase-admin');
admin.initializeApp();
exports.emojify = functions.database.ref("/messages/{pushId}/text").onWrite((change, context) => {
// if (!change.before.val()) { return null; }
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// I tried with this and without it, but neither helped.
const original = change.after.val();
const emojified = original.replace(/\b(H|h)appy\b/ig, "😀");
return admin.database().ref("/messages/{pushId}/text").update(emojified);
});
The closest I got was to actually make it erase everything in the base, including the path messages
and replace it with the written text, with the text replaced by the emoji. Something like:
But it was using set()
instead of update()
, which didn't show any sign of modifying anything.
Upvotes: 0
Views: 651
Reputation: 83048
const original = change.before.val();
is the data before the write. So if there was no data at the "/messages/{pushId}/text"
node before you write there, the variable original
will be null.
You shoud change to:
const original = change.after.val();
which is the data after the write, i.e. your new data, which you want to "emojify".
Update following your comments below
You should use the update()
method (doc here), as follows:
return admin.database().ref("/messages/" + context.params.pushId + "/").update({ text: emojified });
Upvotes: 0