Search code examples
javascriptfirebasegoogle-cloud-platformfirebase-realtime-databasegoogle-cloud-functions

For or While with Javascript and Firebase Realtime Database


Is this possible with Firebase and Javascript? I have a realtime Database which looks like this: P1

Now I want to get access to this database and copy these two parent string into an array. After that I want a for or while loop where this function below gets executed but one time with the first string and the second time with the second string.

This is the code:

var ref = db.ref('/user/' + >>Place String<< + '/notification/'+ subMessageID + '/subMessageID/').set(subMessageID);

The result should be the same as if I would have typed this:

var ref = db.ref('/user/' + 'PpRWBqHFYlg78vSeutNOAPMG3wv1' + '/notification/'+ subMessageID + '/subMessageID/').set(subMessageID);
var ref = db.ref('/user/' + 'hSzkimAs1fWgNke9stnQnf7cNyi2' + '/notification/'+ subMessageID + '/subMessageID/').set(subMessageID);

The path till notification is known. But I don't know how many strings are stored in notification. So it needs to get all of them.

I watched this tutorial here with while and for loops but they work with arrays.

Updated code: What If I have to add multiple things to my database like this instead of only one line like above?

var ref = db.ref('/user/' + >>Place String<< + '/notification/'+ subMessageID + '/subMessageID/').set(subMessageID);
 var ref = db.ref('/user/' + >>Place String<< + '/notification/'+ subMessageID + '/userTime/').set(userTime);
 var ref = db.ref('/user/' + >>Place String<< + '/notification/'+ subMessageID + '/userName/').set(nameUser);

Suggested code:

 function checkpath() {
            var db = admin.database();
            var ref =  db.ref('placeID/here:pds:place:276u0wuu-237aa2acb3b9ce0/-ND4CBIpq7Pds/notification');
            ref.get()
            .then((snapshot) => {
              if (snapshot.exists()) {
                console.log("snapshot existiert und daten wurden auf user eingetragen");

                const keyArray = Object.keys(snapshot.val());
                // We pass an Array of Promises to Promise.all(), see the doc (link below)
                return Promise.all(keyArray.map(k => db.ref('/user/' + k + '/notification/' + subMessageID + '/subMessageID/').set(subMessageID), db.ref('/user/' + k + '/notification/' + subMessageID + '/userTime/').set(userTime)));
              } else {
                console.log('No data available');
                return null;
                // Or throw an error, it's up to you to decide depending on the desired flow of actions
              }
            })
        }

Solution

  • Preamble: Since you tagged your question with the google-cloud-functions tag, I make the assumption you are using the the non-modular Admin SDK.

    If I correctly understand your question, the following should do the trick (using the Admin SDK in a Cloud Function):

      db.ref('placeID/here:pds:.../-NCe5.../notification')
        .get()
        .then((snapshot) => {
          if (snapshot.exists()) {
            const keyArray = Object.keys(snapshot.val());
            // We pass an Array of Promises to Promise.all(), see the doc (link below)
            return Promise.all(keyArray.map(k => db.ref('/user/' + k + '/notification/' + subMessageID + '/subMessageID/').set(subMessageID)));
          } else {
            console.log('No data available');
            return null;
            // Or throw an error, it's up to you to decide depending on the desired flow of actions
          }
        })
        .then(() => {
           return null;  // See https://firebase.google.com/docs/functions/terminate-functions !!IMPORTANT when writing a CF
        })
        .catch((error) => {
          console.error(error);
        });
    

    We use Object.keys() to get the keys of the Object returned by snapshot.val() and Promise.all() to call several times the asynchronous.


    The async/await version would be:

      const snapshot = await db.ref('placeID/here:pds:.../-NCe5.../notification').get();
      if (snapshot.exists()) {
            const keyArray = Object.keys(snapshot.val());
            await Promise.all(
            keyArray.map((k) =>
                db
                .ref(
                    '/user/' +
                    k +
                    '/notification/' +
                    subMessageID +
                    '/subMessageID/'
                )
                .set(subMessageID)
            )
            );
      } else {
            console.log('No data available');
      }
      return null;
    

    Finally, note that instead of using Promise.all() you could use the update() method for writing in an atomic manner several nodes to the DB, as explained here in the doc (see the V8 code version, which corresponds to the non-modular Admin SDK syntax).