Trabajo con colecciones en Firebase y Javascript

  • Por
Aprendemos a crear colecciones de elementos dentro de Firebase, acceder a ellas y suscribirnos a cambios en las colecciones, tanto si se generan nuevos elementos como si éstos cambian.

En esta práctica con Firebase vamos a aprender a trabajar con colecciones de elementos, es decir, listas de items que podamos tener en la base de datos bajo un campo. Haremos básicamente un ejercicio en el que insertaremos datos en una colección y luego otro ejercicio para mostrar esos datos, que a su vez tendrá dos grandes bloques: la operativa para mostrar nuevos elementos en la colección cuando sean creados y la operativa para actualizar la página cuando se produzcan cambios.

Estamos empezando con Firebase, pero ya hay algunas cosas que hemos aprendido como son las referencias y los eventos con los que suscribirnos a cambios en el modelo de datos. Basaremos las explicaciones en ese conocimiento, por lo que si aun tienes dudas te recomendamos repasar el artículo de iniciación a Firebase.

También vimos anteriormente cómo realizar operaciones de escritura y lectura de documentos, la diferencia ahora es que no vamos a escribir y leer un documento, sino una colección. Por ejemplo, en tu base de datos de Firebase podrías tener un usuario con sus datos. Cada usuario es un "documento". Pero nuestra aplicación podrá manejar un número indeterminado de usuarios, por lo que tendremos una colección de usuarios.

En Firebase no hay arrays

Esto es un detalle importante de conocer previamente nos enfrentemos a esta práctica. Merece la pena verlo con detalle detenidamente más adelante, pero de momento simplemente lo vamos a mencionar para ir directamente a la práctica.

Tenlo en cuenta, en Firebase no tenemos arrays. Por eso, aunque lo más inmediato sería pensar que nuestra colección de usuarios se encuentra en un array, lo cierto es que no va a ser así. La colección en Firebase está compuesta por un objeto cuyas propiedades son el índice de la colección y el valor es el objeto de cada item. Lo verás con detalle en la siguiente imagen y en seguida practicaremos con ello.

Observa que cada juego está metido en un objeto. Cada uno de los objetos juego tiene lo que se llama un identificador, que es una cadena alfanumérica muy rara como "-K980osTuGiK0aRZ9t_3". De este identificador cuelga un objeto con los datos del item. Ten en cuenta estos identificadores generados aleatoriamente por Firebase porque los utilizaremos más adelante para nuestra operativa en la programación.

Método push() para insertar un item en una colección

En Firebase cuando queremos insertar un item en una colección, y no nos importa que identificador se le asigne, podemos usar push().

El método push() genera un item con un identificador aleatorio y nos devuelve una referencia a ese item generado. Sobre esa referencia devuelta podremos luego invocar el método set() para cargar cualquier dato.

var ref = new Firebase("https://ejemplo.firebaseio.com/juegos");
var refItem = ref.push();
refItem.set({
	propiedad: "Valor"
});

Esta operativa de generar el item con push() y luego invocar set() se puede reducir a un solo paso, enviando a push() el dato que queremos asignar al item recién creado.

var ref = new Firebase("https://ejemplo.firebaseio.com/juegos");
ref.push({
	propiedad: "Valor"
});

Además, como segundo parámetro, push() podría recibir una función callback que se ejecute cuando el dato se haya guardado dentro de Firebase.

En el siguiente código insertamos tres objetos juego sobre una referencia.

var ref = new Firebase("https://ejemplo.firebaseio.com/juegos");
var juego1 = {
	name: "Colonos de Catán",
	author: "Klaus Teuber",
	yearPublished: 1995
}
ref.push(juego1);
var juego2 = {
	name: "Carcassonne",
	author: "Klaus-Jürgen Wrede",
	yearPublished: 2000
}
ref.push(juego2);
var juego3 = {
	name: "Ticket to Ride: Europe",
	author: "Alan R. Moon",
	yearPublished: 2005
}
ref.push(juego3);

Acceso a elementos de una colección

Espero que recuerdes las explicaciones de los anteriores artículos en las que hablamos de la necesidad de usar eventos para acceder a datos de Firebase, básicamente porque los datos pueden cambiar con el tiempo y Firebase te lo tiene que notificar. Seguimos en la misma necesidad ahora que trabajamos con colecciones.

En el caso que queramos acceder a varios item de una colección y realizar algo para cada uno de esos item, como mostrarlo en pantalla, tenemos que usar el evento "child_added" sobre la referencia.

Este evento "child_added" se ejecuta cada vez que un objeto es añadido a una colección. De modo que se disparará el evento cuando:

  1. Una vez por cada item existente en la colección en el caso que estemos accediendo a una colección por primera vez.
  2. Posteriormente al primer acceso el evento se disparará una vez para cada item que se introduzca dentro de la colección.

De modo que, para nuestra necesidad, acceder a los elementos de una colección, usaremos este evento, que nos servirá para recuperar los item actuales hacer cosas con cada item que pueda llegar a introducirse más adelante en la base de datos.

ref.on("child_added", function(snapshot){
	//hacer cosas con cada snapshot
});

El manejador de eventos asociado a child_added recibe la instantánea del elemento actual. Si hay 10 elementos en la colección este manejador se ejecutará 10 veces y en cada ejecución tendremos el item actual. Ya solo nos quedaría hacer cosas con ese snapshot.

Para la operativa te interesará conocer dos métodos pertenecientes a los snapshots de Firebase:

  • val(): que nos devuelve el valor, el dato, ya sea un objeto o un dato simple.
  • key(): que nos devuelve el identificador de este item.

En el siguiente código, para cada juego recibido, se muestran sus valores y llaves mediante console.log().

var ref = new Firebase("https://juegosdemesa.firebaseio.com/juegos/");
ref.on("child_added", function(snapshot){
	console.log("El juego actual es ", snapshot.val());
	console.log("El id actual es ", snapshot.key());
});

Podrás comprobar que se listan los elementos iniciales de la colección y, si más adelante se agregan nuevos elementos, se listarán igualmente.

Cómo suscribirse a cambios en los elementos

El evento que acabamos de conocer, "child_added", solo nos notificará de nuevos elementos agregados a la colección. Pero sin duda más pronto que tarde querrás saber cuándo los elementos de una colección han sufrido cambios. Eso lo consigues con el evento "child_changed".

Cada vez que un item en una colección que dependa de una referencia cambie, se invocará el manejador de evento "child_changed". El cambio en el item puede ser en cualquiera de sus propiedades o en cualquiera de sus hijos anidados.

El manejador recibe un snapshot igualmente, por lo que la operativa es similar a lo que acabamos de explicar.

ref.on("child_changed", function(snapshot){
	console.log("Detectado cambio en ", snapshot.key());
	console.log("El nuevo valor es ", snapshot.val());
});

Vídeo con una práctica de lectura y escritura de colecciones

Para completar las explicaciones anteriores hemos creado un vídeo que esperamos pueda aclararte mucho mejor toda la operativa de acceso a colecciones, tanto para lectura como escritura.

En este vídeo verás cómo se crean colecciones y se almacenan en la base de datos de Firebase. Luego veremos cómo acceder a colecciones, para mostrar sus valores y suscribirse a los cambios que se produzcan, tanto cuando se inserten nuevos item a la colección como cuando uno de los item sufra un cambio. Esperamos que lo disfrutes.

Autor

Miguel Angel Alvarez

Miguel es fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Comenzó en el mundo del desarrollo web en el año 1997, transformando su hobby en su trabajo.

Compartir

Comentarios

Sergi Olguer

27/6/2016
Arrays muy bien explicado
Hola, Muy bien aclarado el concepto de array en Firebase, que no es tal, sino una colección. Resulta complejo para los que estamos acostumbrados a otros modelos de almacenamiento de los datos.