Home > Software design >  How to listen to realtime database changes (like a stream) in firebase cloud functions?
How to listen to realtime database changes (like a stream) in firebase cloud functions?

Time:05-16

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.

  • Related