Am I using ForEach correctly?

2020-06-25 02:03发布

问题:

I'm working on a presence-like system in firebase with following layout:

firebase {
   user1 {
     isOnline: true
   }
   user 2 {
     isOnline: true
   }
   user3 {
     isOnline: false
   }
}

The isOnline booleans are what I am going to use later to output the names of the users that are online to the console

So for example, in the case above it would say:

user1 is online.
user2 is online.

Here is my code:

var gameRef = new Firebase("https://xxx.firebaseio.com/");
var userOnline = new Firebase('https://xxx/.info/connected');

        userOnline.on('value', function (snapshot) {
          if (snapshot.val()) {
               gameRef.child(user).update({
                    isOnline : true
                });
          }
          else {
              gameRef.child(user).update({
                    isOnline : false
                });
          }
        });

       // for each user that is online, output to the console
       gameRef.forEach(function (snapshot) {
            var obj = snapshot.val();
            if(obj.isOnline == true) {
                console.log(obj.name + " is online.");
            }
        }); 

There seems to be a problem with my forEach, how can I fix this? Thanks.

回答1:

You cannot forEach over a ref, but only over a snapshot.

   // for each user that is online, output to the console
   gameRef.on('value', function(function(gamesSnapshot) {
       gamesSnapshot.forEach(function (snapshot) {
           var obj = snapshot.val();
           if(obj.isOnline == true) {
               console.log(obj.name + " is online.");
           }
       }
   }); 

This code has two snapshot variables:

  • gameSnapshot is the data in the parent node
  • snapshot is the data of a specific player

Alternative

The approach above will download all players, even though you are only looking to deal with players that are online. It is more efficient in this case, to query Firebase so that it only returns players that are online.

   // for each user that is online, output to the console
   var onlinePlayers = gameRef.orderByChild('isOnline').equalTo(true);
   onlinePlayers.on('child_added', function(function(snapshot) {
       var obj = snapshot.val();
       if(obj.isOnline == true) {
           console.log(obj.name + " is online.");
       }
   }); 

The code now listens for the child_added event, since Firebase spoon-feeds us the players one at a time. You will probably also have to handle child_changed and child_removed, once you map the players to HTML elements.

Even though this will result in a bit more code, I would normally recommend using querying and the child_* events, since they limit the data that Firebase sends you both initially and when e.g. a player goes offline.



标签: firebase