firebase and node js : event when value added to the list

1.2k views Asked by At

I am using firebase on node js.

below is my data model

"sList" : {
    "-K_KxnexiRMvC81bTEVH" : {
          "description" : "sdf",
          "name" : "sdf",
          "users" : [ "-K_Kxnf9XBnClTgFv67z", "-K_KvlWOiNCOBDL-Vl3y" ]
        },
    "-K_KxnexiRMvC81asdabTEVHas" : {
          "description" : "sdf",
          "name" : "pdsff",
          "users" : [ "-K_Kxnf9XBnClTgasv67z", "-K_KvlWOiNCsadOBDL-Vl3y" ]
        },
}

unique id's will be added to the users array in each document.

How can i add an event listener over all the users array in each document whenever the unique id is added

Below code i have tried, but not working

var listRef = firebaseAdmin.database().ref('/sList');

listRef.on('child_changed', function(dataSnapshot) { 
    const msg= dataSnapshot.val();
    const key= dataSnapshot.key();
    var userRef = listRef.child();
    userRef.on('child_changed', function(childDataSnapshot) {
        const val=childDataSnapshot.val();
     });
})
1

There are 1 answers

1
Frank van Puffelen On

You're violating two of Firebase's recommendations here:

  1. don't nest data
  2. don't store data in arrays

Don't nest data

You're mostly bitten by the nesting here: if you want to listen to just the users of a sList, you should store that data separately. Luckily this is easy to fix:

"sList" : {
    "-K_KxnexiRMvC81bTEVH" : {
          "description" : "sdf",
          "name" : "sdf",
        },
    "-K_KxnexiRMvC81asdabTEVHas" : {
          "description" : "sdf",
          "name" : "pdsff",
        },
},
"sListUsers": {
    "-K_KxnexiRMvC81bTEVH" : [ "-K_Kxnf9XBnClTgFv67z", "-K_KvlWOiNCOBDL-Vl3y" ],
    "-K_KxnexiRMvC81asdabTEVHas" : [ "-K_Kxnf9XBnClTgasv67z", "-K_KvlWOiNCsadOBDL-Vl3y" ]
}

So we keep two lists with the same keys, that way you can look up either the users or the metadata for a sList.

Listening for the users then becomes a simple matter of:

var listRef = firebaseAdmin.database().ref('/sListUsers/-K_KxnexiRMvC81bTEVH');

listRef.on('child_added', function(dataSnapshot) { 
    const user = dataSnapshot.val();
})

Don't store data as arrays

The second problem is that you're storing your users in an array: an ordered collection of non-unique values. But if we look at what you have, it is much more likely that you want to store the users in an (possibly unordered) collection of unique values. Such a collection type is typically referred to as a set.

In Firebase a set of your users is modeled as:

When applied to your data mode, it turns into:

"sList" : {
    "-K_KxnexiRMvC81bTEVH" : {
          "description" : "sdf",
          "name" : "sdf",
        },
    "-K_KxnexiRMvC81asdabTEVHas" : {
          "description" : "sdf",
          "name" : "pdsff",
        },
},
"sListUsers": {
    "-K_KxnexiRMvC81bTEVH" : { 
        "-K_Kxnf9XBnClTgFv67z": true, 
        "-K_KvlWOiNCOBDL-Vl3y": true
    },
    "-K_KxnexiRMvC81asdabTEVHas" : {
        "-K_Kxnf9XBnClTgasv67z": true, 
        "-K_KvlWOiNCsadOBDL-Vl3y": true
    }
}

The true here is a just a marker value, since Firebase cannot store keys without values. The important thing is that we're storing the user's ids as keys, which are guaranteed to be unique.

You'd get the users from here with:

var listRef = firebaseAdmin.database().ref('/sListUsers/-K_KxnexiRMvC81bTEVH');

listRef.on('child_added', function(dataSnapshot) { 
    const user = dataSnapshot.key;
})