Return a firebase database reference as an array in a cloud function

4k views Asked by At

Below is the firebase database reference returned as an array in my AngularJS scope:

var ref = firebase.database().ref("users").child(user.uid).child("week1");
$firebaseArray(ref);

However when I tried writing the same code in my index.js file for a database Cloud Function, there was an error message:

ReferenceError: $firebaseArray is not defined at /user_code/index.js:22:18

Is there a way to make a Firebase reference ref return as an array in my index.js Cloud Functions file since $firebaseArray is not defined outside the AngularJS scope?

Below is an illustration of the database:

 users: {
   user uid (generated by push) : {
       deviceToken : "tokenID",
       name : "Display Name"
   },
   anotherUserID : {
       deviceToken : "tokenID",
       name : "Display Name"
   },
Players: {
    player1: John,
    Player2: ken,
}

Is there a way for a change in the Players database node to trigger a function in the users node (for each user):

exports.update = functions.database.ref('/Player')
    .onWrite(event=>{
      console.log(event.data);
      var ref = admin.database().ref('/users/'+ user.uid+ '/week1');
      ref.set(10);
      return;
    });

My issue was accessing the user.uid (created by the push() method) for each user.

1

There are 1 answers

10
Grimthorr On BEST ANSWER

In Cloud Functions, you can use the Firebase Admin SDK to save and retrieve data from the database. To initialize the Admin SDK, you can use environment configuration:

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);

You can then attach a value listener to your database reference, utilizing and returning a JavaScript Promise to keep the function alive and chain your logic:

const ref = admin.database().ref("/users").child(user.uid).child("week1");

return ref.once("value").then(snapshot => {
    const values = snapshot.val();

    // Do something with the snapshot
});

The values variable here will be assigned an array of the values at the location (see val()), so could be used in place of $firebaseArray.


If you need to obtain a reference to the node that triggered your database function, you can use the event parameter from the function definition:

let ref = event.data.ref;

This is useful if you need to obtain the specific location in the database that triggered your function. The event.data variable is a DeltaSnapshot instance for database functions.

Similarly, you can use event.params to obtain any of the variables specified in a database trigger definition, for example {uid} in the below definition can be obtain using event.params.uid:

exports.example = functions.database.ref('/users/{uid}')
    .onWrite(event => {
      const uid = event.params.uid;
      // ...
    });

The method you take here depends on what work you need your function to perform, how it's triggered and what variables or values you need access to.

Remember that your function can freely read and write data anywhere in the database using the Admin SDK too.


In your newest example, it would be hard to match a node at /players to /users because there isn't a value with the user's UID. So you would need to change the /players child nodes to include further data, something like:

players : {
    player1 : {
        name: "John",
        uid: "anotherUserID"
    }
}

You could then extract this uid using event.data.child('uid').val() from your function (where your function is triggered by children under this node using /players/{playerId}):

exports.update = functions.database.ref('/players/{playerId}')
    .onWrite(event=>{
      console.log(event.data);
      const uid = event.data.child('uid').val();
      var ref = admin.database().ref('/users/' + uid + '/week1');
      ref.set(10);
      return;
    });