I am trying to listen to the changes in a specific field in a specific document in Firebase Realtime database. I am using Node JS for the cloud functions. this is the function.
const functions = require("firebase-functions");
const admin = require('firebase-admin');
admin.initializeApp(functions.config.firebase);
const delay = ms => new Promise(res => setTimeout(res, ms));
exports.condOnUpdate = functions.database.ref('data/').onWrite(async snapshot=> {
const snapBefore = snapshot.before;
const snapAfter = snapshot.after;
const dataB = snapBefore.val();
const data = snapAfter.val();
const prev= dataB['cond'];
const curr= data['cond'];
// terminate if there is no change
if(prev==curr)
{
return;
}
if(curr==0){
// send notifications every 10 seconds until value becomes 1
while(true){
admin.messaging().sendToTopic("all", payload);
await delay(10000);
}
}else if(curr==1){
// send one notification
admin.messaging().sendToTopic("all", payload);
return;
}
});
The function works as expected but the loop never stops as it never exists the loop, instead, the function runs again (with new instance I suppose).
so is there any way to listen to the data changes in one function just like streams in other languages, or perhaps stop all cloud functions from running.
Thanks in advance!
CodePudding user response:
From the comments it seems that the cond
property is updated from outside of the Cloud Function. When that happens, it will trigger a new instance of the Cloud Function to run with its own curr
variable, but it won't cause the curr
value in the current instance to be updated. So the curr
variable in the original instance of your code will never become true, and it will continue to run until it times out.
If you want the current instance to detect the change to the property, you will need to monitor that property inside the code too by calling onValue
on a reference to it.
An easier approach though might be to use a interval trigger rather than a database trigger to:
- have code execute every minute, and then in there
- query the database with the relevant
cond
value, and then - send a notification to each of those.
This requires no endless loop or timeouts in your code, which is typically a better approach when it comes to Cloud Functions.