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 Expressexports.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 versionadaapp.post('/v1',(req, res, next)=>{returnpostControl(req.body.Data, req.body.Topico).then(()=> res.status(200).json({resultado:true})).catch(error=>next(newError(error.toString())));});// Middleware de errores reutilizableapp.use((error, req, res, next)=>{// Respuesta estándar de errorreturn res.status(500).json({response_error: error.message});// Log opcionalconsole.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?