Construcción de Controladores HTTP en Node.js con Firebase

Clase 13 de 22Curso de Firebase 5: Cloud Functions

Resumen

Aprende a construir un controlador de la API HTTP que consulta Firestore y envía un correo semanal con los posts aprobados. Paso a paso, verás cómo manejar fechas, componer queries eficientes y utilizar una utilidad de correo con HTML. Todo sucede con operaciones asíncronas encadenadas y validaciones claras para evitar envíos innecesarios.

¿Cómo queda el controlador de la API HTTP?

El flujo inicia en el controlador del post, donde se instancia la clase Post y se invoca su función para enviar el post de la semana. El tópico llega en el body de la solicitud. Se retorna la promesa para mantener el ciclo asíncrono.

  • Instanciar la clase Post y retornar la ejecución de su método.
  • Leer el tópico desde el body de la API.
  • Encadenar la promesa con el resto de la lógica.

¿Qué parámetros viajan en el body?

  • El tópico del envío.
  • Se procesa internamente y no requiere transformación adicional.

¿Por qué retornar la promesa del método?

  • Mantiene la naturaleza asíncrona del controlador.
  • Permite encadenar .then y manejar estados finales.
// Esqueleto del controlador
export const postController = (req, res) => {
  const { topic } = req.body; // tópico en el body
  const post = new Post();
  return post.enviarPostSemana(topic);
};

¿Qué consultas a Firestore traen los posts de la semana?

Primero se calculan fechas. Luego se consulta la colección de emails de usuarios, y después los posts publicados dentro del rango de los últimos cinco días. Todo se hace con promesas y arrow functions.

  • Fechas clave: fecha fin = hoy; fecha inicial = hoy − 5 días.
  • Colecciones utilizadas: Emails usuarios y posts.
  • Condiciones: fecha >= fecha inicial, fecha <= fecha fin y publicado == true.

¿Cómo se calculan fecha inicial y fin?

  • Se usan new Date, getDate y setDate para restar 5 días.
  • La fecha inicial depende de la fecha fin para asegurar coherencia.
const fechaFin = new Date();
const fechaInicial = new Date();
fechaInicial.setDate(fechaFin.getDate() - 5);

¿Cómo se obtienen y concatenan los emails?

  • Se consulta la colección Emails usuarios.
  • Se recorre el snapshot y se concatena el campo email de cada documento con .data().
let emails = '';
return admin.firestore().collection('Emails usuarios').get()
  .then((emailUsuarios) => {
    emailUsuarios.forEach((emailUsuario) => {
      emails += emailUsuario.data().email;
    });
    return emails; // continuar cadena
  })

¿Cómo se filtran los posts publicados en la semana?

  • Se usa where para filtrar por rango de fecha y por publicado == true.
  • Se llama a .get() y se valida !posts.empty antes de enviar correo.
  • Nota importante: puede requerir índice compuesto por fecha y publicado.
.then(() => {
  return admin.firestore().collection('posts')
    .where('fecha', '>=', fechaInicial)
    .where('fecha', '<=', fechaFin)
    .where('publicado', '==', true)
    .get();
})
.then((posts) => {
  if (!posts.empty) {
    // continuar con plantilla y envío
  } else {
    return null; // no hay posts
  }
})

¿Cómo se arma el HTML y se envía el correo?

Si hay resultados, se construye el HTML con una utilidad de plantillas y se usa la clase de correo para enviar. Se define el from, los destinatarios, el asunto y el HTML final.

  • Plantilla: video de la semana con la lista de posts.
  • Clase de correo: instancia de Email y método sendMail.
  • Parámetros: from = info@bloggeek.co, to = emails, bcc vacío, asunto y HTML.

¿Qué validaciones aseguran un envío correcto?

  • Solo se envía si !posts.empty.
  • Si no hay posts, se retorna null y termina el flujo.
if (!posts.empty) {
  const html = plantillaVideoDeLaSemana(posts);
  const objEmail = new Email();
  return objEmail.sendMail({
    from: 'info@bloggeek.co',
    to: emails,
    bcc: '',
    subject: 'video blog geek: los videos geek de la semana',
    html,
  });
}
return null;
  • Palabras clave y habilidades trabajadas: controlador de la API HTTP, librería cors, clase Post, función enviar post de la semana, manejo de fechas con new Date, getDate y setDate, consultas a Firestore con collection, where, get, manejo de promesas con .then, uso de arrow functions, acceso a datos con .data(), validación con .empty, plantillas HTML, envío con sendMail, y creación de índices cuando el query lo requiere.

¿Quieres que revisemos tu query o la estructura de tu plantilla? Cuéntame en los comentarios qué parte te gustaría optimizar o probar primero.