Implementar consultas en tiempo real con Firestorm/Firestore te permite mostrar cambios sin recargar ni hacer polling. Con una suscripción a la colección, la base de datos notifica inserciones, actualizaciones y eliminaciones. Así, el blog se mantiene ágil y sincronizado, mejorando el rendimiento y la experiencia.
¿Qué es real time en Firestorm y por qué mejora el rendimiento?
La idea clave: la base de datos envía eventos cuando cambian los datos. No necesitas consultar constantemente. Otras aplicaciones pueden insertar, actualizar o borrar, y tu app recibe el aviso al instante.
Suscripción a una colección con onSnapshot.
Recepción automática de cambios: agregar, modificar o eliminar documentos.
Menos consultas repetitivas y renderizado más eficiente.
¿Cómo funciona la suscripción con onSnapshot?
Se obtiene la instancia de Firestorm/Firestore, se apunta a la colección "post" y se registra onSnapshot. Este método entrega una copia de los datos en una variable tipo querySnapshot cada vez que se produce un cambio.
Te suscribes a la colección.
Recibes un snapshot actualizado en cada evento.
Procesas los documentos y actualizas la interfaz.
¿Qué datos entrega querySnapshot y cómo tratarlos?
querySnapshot representa el estado actual de la consulta: si está vacío, se muestra un "post vacío" para motivar a crear contenido; si trae documentos, se recorre con foreach y se renderiza cada post con una plantilla HTML.
Verificación de vacío para decidir qué mostrar.
Recorrido con foreach para múltiples documentos.
Limpieza del listado antes de repintar.
¿Cómo pintar y actualizar los posts en tiempo real?
El flujo recomendado: vaciar el contenedor de posts, comprobar si hay datos, y luego construir el HTML con una función de plantilla. Si no hay elementos, se inserta un post genérico (el "post vacío").
¿Cómo manejar el caso sin datos y el post vacío?
Si querySnapshot no contiene documentos, se agrega el resultado de la función "obtener post vacío" para invitar a publicar. Esto asegura una interfaz útil incluso sin contenido.
Mensaje motivador mediante un post genérico.
Interfaz consistente sin listas vacías.
¿Cómo construir el HTML con una plantilla?
Cada documento se pasa a una función que devuelve el template HTML del post. Los campos provienen de post.data() (un objeto JSON): autor, título, descripción, videolink, imágelink y fecha.
Acceso a datos con post.data().
Transformación de fecha: de timestamp a legible con utilidad.estática.
Inserción del HTML en el contenedor de posts.
// Suscripción a todos los posts (esqueleto basado en el flujo descrito)Firestorm.collection('post').onSnapshot((querySnapshot)=>{// 1) Limpiar la lista antes de repintar.// limpiarPosts();if(querySnapshot.empty){// 2) Agregar el post vacío cuando no hay datos.const htmlVacio =obtenerPostVacio();// render(htmlVacio);return;}// 3) Recorrer y pintar cada post. querySnapshot.forEach((post)=>{const data = post.data();// autor, título, descripción, videolink, imágelink, fecha.// 4) Formatear fecha: timestamp -> Date -> string legible.const fechaLegible = utilidad.obtenerFecha(data.fecha.toDate());// 5) Construir HTML con la plantilla.const postHTML =obtenerPostTemplate({autor: data.autor,titulo: data.titulo,descripcion: data.descripcion,videolink: data.videolink,imagelink: data.imagelink,fecha: fechaLegible,});// 6) Agregar al contenedor del blog.// render(postHTML);});});
La función de utilidad convierte timestamp con toDate() y formatea la salida para el usuario.
La plantilla HTML reemplaza valores y devuelve el bloque listo para insertar.
¿Cómo filtrar “Mis posts” con where por autor?
Para ver solo los posts del usuario autenticado, se usa un filtro por el campo "autor". Así, "Mis posts" muestra únicamente documentos cuyo autor coincide con el correo del usuario.
Filtro por igualdad con where.
Registro del escucha en tiempo real para ese subconjunto.
Integración con la acción de clic en "Mis posts".
¿Cómo registrar el escucha al hacer clic en mis posts?
Al activar la opción "Mis posts" y con el usuario autenticado, se llama a la función que suscribe la consulta filtrada por email. También se reutiliza el registro al visitar "Todos los posts" para escuchar toda la colección.
// Consulta en tiempo real solo para el autor indicado.functionconsultarPostPorUsuario(email){Firestorm.collection('post').where('autor','==', email).onSnapshot((querySnapshot)=>{// Limpiar y repintar como en la consulta general.if(querySnapshot.empty){const htmlVacio =obtenerPostVacio();// render(htmlVacio);return;} querySnapshot.forEach((post)=>{const data = post.data();const fechaLegible = utilidad.obtenerFecha(data.fecha.toDate());const postHTML =obtenerPostTemplate({autor: data.autor,titulo: data.titulo,descripcion: data.descripcion,videolink: data.videolink,imagelink: data.imagelink,fecha: fechaLegible,});// render(postHTML);});});}
Al editar un título y actualizarlo, el cambio se refleja en real time sin relanzar la consulta.
"Todos los posts" escucha la colección completa; "Mis posts" aplica el filtro por autor.
¿Tienes dudas o quieres compartir cómo implementaste tu suscripción con onSnapshot y el filtro por autor? Escribe tus comentarios y cuéntanos tu caso.
Consultas en Tiempo Real con Firestore para Aplicaciones Web
Consultas en Tiempo Real con Firestore para Aplicaciones Web
Recursos
Resumen
Implementar consultas en tiempo real con Firestorm/Firestore te permite mostrar cambios sin recargar ni hacer polling. Con una suscripción a la colección, la base de datos notifica inserciones, actualizaciones y eliminaciones. Así, el blog se mantiene ágil y sincronizado, mejorando el rendimiento y la experiencia.
¿Qué es real time en Firestorm y por qué mejora el rendimiento?
La idea clave: la base de datos envía eventos cuando cambian los datos. No necesitas consultar constantemente. Otras aplicaciones pueden insertar, actualizar o borrar, y tu app recibe el aviso al instante.
Suscripción a una colección con onSnapshot.
Recepción automática de cambios: agregar, modificar o eliminar documentos.
Menos consultas repetitivas y renderizado más eficiente.
¿Cómo funciona la suscripción con onSnapshot?
Se obtiene la instancia de Firestorm/Firestore, se apunta a la colección "post" y se registra onSnapshot. Este método entrega una copia de los datos en una variable tipo querySnapshot cada vez que se produce un cambio.
Te suscribes a la colección.
Recibes un snapshot actualizado en cada evento.
Procesas los documentos y actualizas la interfaz.
¿Qué datos entrega querySnapshot y cómo tratarlos?
querySnapshot representa el estado actual de la consulta: si está vacío, se muestra un "post vacío" para motivar a crear contenido; si trae documentos, se recorre con foreach y se renderiza cada post con una plantilla HTML.
Verificación de vacío para decidir qué mostrar.
Recorrido con foreach para múltiples documentos.
Limpieza del listado antes de repintar.
¿Cómo pintar y actualizar los posts en tiempo real?
El flujo recomendado: vaciar el contenedor de posts, comprobar si hay datos, y luego construir el HTML con una función de plantilla. Si no hay elementos, se inserta un post genérico (el "post vacío").
¿Cómo manejar el caso sin datos y el post vacío?
Si querySnapshot no contiene documentos, se agrega el resultado de la función "obtener post vacío" para invitar a publicar. Esto asegura una interfaz útil incluso sin contenido.
Mensaje motivador mediante un post genérico.
Interfaz consistente sin listas vacías.
¿Cómo construir el HTML con una plantilla?
Cada documento se pasa a una función que devuelve el template HTML del post. Los campos provienen de post.data() (un objeto JSON): autor, título, descripción, videolink, imágelink y fecha.
Acceso a datos con post.data().
Transformación de fecha: de timestamp a legible con utilidad.estática.
Inserción del HTML en el contenedor de posts.
// Suscripción a todos los posts (esqueleto basado en el flujo descrito)
Firestorm.collection('post').onSnapshot((querySnapshot) => {
// 1) Limpiar la lista antes de repintar.
// limpiarPosts();
if (querySnapshot.empty) {
// 2) Agregar el post vacío cuando no hay datos.
const htmlVacio = obtenerPostVacio();
// render(htmlVacio);
return;
}
// 3) Recorrer y pintar cada post.
querySnapshot.forEach((post) => {
const data = post.data(); // autor, título, descripción, videolink, imágelink, fecha.
// 4) Formatear fecha: timestamp -> Date -> string legible.
const fechaLegible = utilidad.obtenerFecha(data.fecha.toDate());
// 5) Construir HTML con la plantilla.
const postHTML = obtenerPostTemplate({
autor: data.autor,
titulo: data.titulo,
descripcion: data.descripcion,
videolink: data.videolink,
imagelink: data.imagelink,
fecha: fechaLegible,
});
// 6) Agregar al contenedor del blog.
// render(postHTML);
});
});
La función de utilidad convierte timestamp con toDate() y formatea la salida para el usuario.
La plantilla HTML reemplaza valores y devuelve el bloque listo para insertar.
¿Cómo filtrar “Mis posts” con where por autor?
Para ver solo los posts del usuario autenticado, se usa un filtro por el campo "autor". Así, "Mis posts" muestra únicamente documentos cuyo autor coincide con el correo del usuario.
Filtro por igualdad con where.
Registro del escucha en tiempo real para ese subconjunto.
Integración con la acción de clic en "Mis posts".
¿Cómo registrar el escucha al hacer clic en mis posts?
Al activar la opción "Mis posts" y con el usuario autenticado, se llama a la función que suscribe la consulta filtrada por email. También se reutiliza el registro al visitar "Todos los posts" para escuchar toda la colección.
// Consulta en tiempo real solo para el autor indicado.
function consultarPostPorUsuario(email) {
Firestorm
.collection('post')
.where('autor', '==', email)
.onSnapshot((querySnapshot) => {
// Limpiar y repintar como en la consulta general.
if (querySnapshot.empty) {
const htmlVacio = obtenerPostVacio();
// render(htmlVacio);
return;
}
querySnapshot.forEach((post) => {
const data = post.data();
const fechaLegible = utilidad.obtenerFecha(data.fecha.toDate());
const postHTML = obtenerPostTemplate({
autor: data.autor,
titulo: data.titulo,
descripcion: data.descripcion,
videolink: data.videolink,
imagelink: data.imagelink,
fecha: fechaLegible,
});
// render(postHTML);
});
});
}
Al editar un título y actualizarlo, el cambio se refleja en real time sin relanzar la consulta.
"Todos los posts" escucha la colección completa; "Mis posts" aplica el filtro por autor.
¿Tienes dudas o quieres compartir cómo implementaste tu suscripción con onSnapshot y el filtro por autor? Escribe tus comentarios y cuéntanos tu caso.
Estos tutoriales (algunos en ingles 🇺🇸) son muy útiles para complementar lo que aprendimos en la clase y ver las otras formas (o no 😅) de consumir la información de Firetore en tiempo real con otros proyectos 👍:
Firebase Firestore Tutorial - Real-time Data
Obtener actualizaciones en tiempo real con Cloud Firestore
Les dejo una actualización en el archivo de util.js
Puesto que la fecha no se muestra con el formato correcto NAN/NAN/NAN a consecuencia de cambios en en la API de firestore
class Utilidad {
static obtenerFecha (timeStamp) {
// El cambio es llamar al atributo seconds
const d = new Date(timeStamp.seconds)
console.log(timeStamp);
console.log(d);
let month = '' + (d.getMonth() + 1)
let day = '' + d.getDate()
let year = d.getFullYear()
if (month.length < 2) month = '0' + month
if (day.length < 2) day = '0' + day
return [day, month, year].join('/')
}
}
Eso de que Firebase nos notifique cada vez que hay algún cambio en las BDs en vez de nosotros consultar cada segundo (haciendo nuestra aplicación cada vez más lenta) es mágico 😍🔥🎉.
Tuve que quitar el constructor de la clase Post y llevarlo al archivo general.js para poder crear otro post pues me aparecio un error en consola que decia que la firestore ya habia sido inicializado y los "settings" ya habian seteados y no podian modificarse.
Deduzco que al existir al menos un post éste se mostraba en el front y por lo tanto, se inicializaba firestore. Por ello el error y algún cambio en la API. Puesto que, cuando el profesor lo ejecutó, todo era correcto.
<------------------------->
Añado un pequeño "hack" que realicé para poder mostrar los videos de youtube:
Click derecho en el video a insertar y seleccionar copiar código de inserción.
Copiar el código en algún lugar(bloc de notas, editor de codigo, etc) y copiar el src que nos brindará youtube para usar en el iframe.
Usar para registrar el video al crear un post y/o actualizar en firestore en caso ya se haya creado el post y tengan problemas con el video.