Firebase : Usuarios online

publicado en la categoría Firebase
Firebase nos permite tener una lista actualizada de los usuarios conectados y detectar las desconexiones que se produzcan ya sea porque se cerró la página o el navegador. De este modo, se puede lograr una interacción que sería imposible de realizar sólo con JavaScript y muy engorrosa con otro lenguaje.

Como utilizamos Firebase para registrar usuarios, eso nos permite tener una lista actualizada permanentemente de aquellos que están conectados. Esto, que es algo conceptualmente simple, suele ser bastante engorroso de realizar porque debemos chequear constantemente ese estado o si hay actividad y, muchas veces, el resultado es relativo; cierro la página y nadie le dice al sistema que me he ido.

Firebase resuelve estos dilemas de modo muy sencillo ya que funciona aunque haya una desconexión temporal. Esto se logra mediante la función OnDisconnect y el dato interno /.info/connected que devolverá true o false indicándonos si el usuario está o no está conectado.

Bueno ... nada es tan simple ... en realidad, el estado de los usuarios no se transmite a todos ellos de modo automático.

¿Qué quiero decir? Que si Fulano y Mengano están en nuestra página y uno de ellos cierra el navegador y se conecta, el otro no se entera pero Firebase sí. Por eso debemos usar nuestra propia base de datos para ir guardando esos estados; la llamaremos statusonline:

var refDATABASE = firebase.database(); // referencia a nuestra base de datos
var user = firebase.auth().currentUser; // los datos del usuario actual
// observador que establece al usuario actual como conectado/desconectado
var refYO = refDATABASE.ref('statusonline/'+user.uid); // referencia al usuario actual
refDATABASE.ref('.info/connected').on('value', function(data){
	if(data.val()){
		refYO.onDisconnect().remove();
		refYO.set({name:user.displayName}); // agregamos el nombre o cualquier otro dato
	}
});

De este modo nuestra base de datos siempre contendrá una lista con los identificadores de los usuarios online y sus nombres. Lo que faltaría es que todos los usuarios pudieran tener acceso a esa lista y eso lo conseguimos observando sus cambios.

Por ejemplo, podríamos tener un array con la lista de usuarios conectados pero eso dependerá de lo qué queremos mostrar en cada caso en particular:

var arrONLINE = []; // el array con los datos de los usuarios conectados

// observamos la tabla de usuarios conectados para detectar cambios
refDATABASE.ref('statusonline/').on('value', function(data){
	arrONLINE.splice(0, arrONLINE.length); // vaciamos el array
	// leemos los items de la tabla
	$.each(data.val(), function(uid,val){
		arrONLINE.push(val); // los agregamos al array		
	});
	alert(arrONLINE.length+' usuarios conectados');
});

¿Qué haremos con ese array? Eso es arena de otro costal ... sólo hay que recordar que estamos usando métodos y funciones que se ejecutan de modo asincrónico por lo tanto, siempre debemos agregar todos esos observadores dentro de onAuthStateChanged una vez que el usuario ha sido reconocido, caso contrario, sólo recibiremos errores o nada.

Podríamos modificar el ejemplo original de este modo:

window.onload = function(){
	firebase.auth().onAuthStateChanged(function(user){
		if(user){
			 // el usuario está logueado
			mostrarUsuario(user); // mostraremos sus datos y el botón de cerrar sesión
			// ******* AQUÍ AGREGARÍAMOS EL CÓDIGO *******
		} else {
			 // el usuario NO está logueado
			$('#logintest').show(); // hacemos visible el botón de iniciar sesión
		}
	});
}