Funciones HTTP con Express en Firebase

Clase 12 de 22Curso de Firebase 5: Cloud Functions

Resumen

Domina cómo exponer funciones HTTP en Firebase con Express y CORS para crear APIs seguras y personalizables. Aquí verás cómo elegir entre on call y on request, configurar rutas versionadas como /v1, procesar el body en JSON y manejar errores con un intermediario centralizado.

¿Qué diferencia a on call y on request en Firebase Functions?

Las funciones on call y on request resuelven necesidades distintas. Elegir bien impacta la seguridad y la forma de invocación.

  • on call: recibe el contexto del usuario y el token. Requiere el SDK de Firebase para Android, iOS o web. La validación del token ocurre automáticamente.
  • on request: se invoca como HTTP puro, sin SDK. Útil cuando se necesita llamar la función desde cualquier cliente o servicio externo.

En este caso se opta por on request para exponer la función como API y permitir llamadas directas.

¿Cómo configurar Express y CORS en una función HTTP?

Para enriquecer la función HTTP, se integra Express por su flexibilidad al definir rutas, métodos y middlewares; y se agrega CORS para permitir solicitudes desde otros dominios cuando es necesario.

  • Instalar dependencias dentro de la carpeta de functions.
  • Comando usado para Express: npm install --safe express.
  • Importar y configurar Express y CORS.
const express = require('express');
const cors = require('cors');

const app = express();
app.use(cors());

// Exportar la función HTTP (expuesta como API)
// functions.https.onRequest manejará las solicitudes con Express
exports.enviarPostsDeLaSemana = functions.https.onRequest(app);

Claves de esta configuración: - CORS habilitado: permite llamadas desde otro dominio cuando aplique. - Express como capa de enrutamiento y middlewares. - La función queda expuesta como API mediante HTTP.

¿Cómo manejar rutas, body y errores con Express?

Con Express puedes definir rutas versionadas y métodos específicos. Además, centralizas el manejo de errores con un middleware para respuestas consistentes.

  • Ruta y método: app.post('/v1', ...) para versionar el endpoint y aceptar solo POST.
  • Datos de entrada: el body llega en JSON con campos como Data y Topico.
  • Respuesta de éxito: status 200 y { resultado: true }.
  • Errores: se propagan con next(new Error(error.toString())) y un middleware responde con status 500 y el mensaje.
// Ruta POST versionada
app.post('/v1', (req, res, next) => {
  return postControl(req.body.Data, req.body.Topico)
    .then(() => res.status(200).json({ resultado: true }))
    .catch(error => next(new Error(error.toString())));
});

// Middleware de errores reutilizable
app.use((error, req, res, next) => {
  // Respuesta estándar de error
  return res.status(500).json({ response_error: error.message });

  // Log opcional
  console.error('error', error);
});

Buenas prácticas destacadas: - Versionar rutas: por ejemplo, /v1 para facilitar cambios futuros. - Usar middlewares: validación de parámetros, seguridad y captura de errores. - Estandarizar respuestas: códigos 200 para éxito y 500 para error con mensaje claro. - Centralizar errores con next: evita duplicar lógica y mejora el mantenimiento.

Este flujo deja lista la función HTTP que, al invocarse con POST en /v1, llama al controlador que envía los posts de la semana y responde de forma consistente ante éxito o falla.

¿Quieres que comentemos cómo validar parámetros en el middleware o cómo estructurar el controlador para enviar correos y notificaciones?