Thinkster
Firebase
Build a Real-Time Slack Clone using AngularFire

Adding Presence to Users

Learn how to use Firebase's presence system to detect when users are currently online or offline

Having direct messaging is an important feature to any chat application, but it's also very useful to know what users are online. Firebase makes this very easy for us. Read the Firebase Documentation to see some example code using presence. While this code is written using the core Firebase library, we're going to replicate the same functionality using AngularFire.

In our Users service, add a reference to the special .info/connected node on your Firebase
var usersRef = firebase.database().ref('users');
var connectedRef = firebase.database().ref('.info/connected');
Create a setOnline function for our Users service.
setOnline: function(uid){
  var connected = $firebaseObject(connectedRef);
  var online = $firebaseArray(usersRef.child(uid+'/online'));

  connected.$watch(function (){
    if(connected.$value === true){
      online.$add(true).then(function(connectedRef){
        connectedRef.onDisconnect().remove();
      });
    }
  });
}

This function watches for changes at the .info/connected node and will $add any open connections to a $firebaseArray keyed under online within the user's profile. This allows us to track multiple connections (in case the user has multiple browser windows open), which will get removed when the client disconnects.

In app/channels/channels.controller.js set the current user as online.
Users.setOnline(profile.$id);
Update our logout function to wipe out the online array when the user logs out
channelsCtrl.logout = function(){
  channelsCtrl.profile.online = null;
  channelsCtrl.profile.$save().then(function(){
    Auth.$signOut().then(function(){
      $state.go('home');
    });
  });
};
Add a presence icon next to the current user's display name in app/channels/index.html
<div class="user-name">
  <span class="presence" ng-class="{online: channelsCtrl.profile.online}"></span>
  {{ channelsCtrl.profile.displayName }}
</div>

We're also dynamically adding the online class to the span tag using ng-class, based on if the $firebaseArray containing connections in the profile is present.

Add a presence icon next to the current user's display name in app/channels/index.html
<a ng-if="user.$id !== channelsCtrl.profile.$id" ui-sref="channels.direct({uid: user.$id})" ui-sref-active="selected">
  <span class="presence" ng-class="{online: user.online}"></span>
  {{ user.displayName }}
</a>

We're now able to see when our users are online! Our application is almost ready for production. In the next sections we will go over securing our data and deploying our application live.

Check your work

You can view the completed & working code for this tutorial here: