Cómo entregar contenido dinámico con Cloud Functions

Firebase Hosting te permite usar Cloud Functions para ejecutar el procesamiento en el servidor. Esto significa que puedes admitir la generación dinámica de contenido para el sitio de Firebase Hosting. Los siguientes son ejemplos de lo que puedes hacer con esto:

  • Procesar contenido dinámico. En lugar de procesar únicamente contenido estático, puedes procesar lógica en el servidor a través de una función para mostrar una respuesta generada de forma dinámica. Por ejemplo, puedes tener una URL como /blog/<id-for-blog-post>. Este patrón de URL puede dirigirse a una función que use el parámetro de ID de la URL de la entrada de blog para recuperar contenido de forma dinámica desde Firebase Realtime Database.
  • Realizar un procesamiento previo para que las apps con una sola página mejoren la SEO. Esto te permite crear etiquetas meta dinámicas para compartir contenido en varias redes sociales.
  • Mantener la aplicación web liviana. Puedes crear una API a través de Cloud Functions para que el sitio de Firebase Hosting recupere contenido de manera asíncrona. Esto te permite reducir los tiempos de carga inicial de la aplicación web, ya que mantiene liviano el código del cliente y carga el contenido de manera asíncrona a través de una función.

Ten en cuenta que Firebase Hosting está sujeto a un tiempo de espera de la solicitud de 60 segundos. En el caso de contenido dinámico que tarde más de 60 segundos en generarse, se recomienda usar el entorno flexible de App Engine.

Conecta Cloud Functions con Firebase Hosting

Para conectar una función con Firebase Hosting, debes configurar Cloud Functions, escribir la función y crear reglas de reescritura para después implementar los cambios. Si quieres mejorar el rendimiento del contenido dinámico, de manera opcional, puedes ajustar la configuración de la caché.

Configura Cloud Functions para Firebase Hosting

Si ya configuraste Cloud Functions para Firebase, puedes omitir este paso y proceder a crear una función HTTP.

Para configurar Cloud Functions en el proyecto, necesitarás la versión más reciente de Firebase CLI, que requiere la versión 6.3.1 de Node.js o superior. Para instalar Node.js, sigue las instrucciones en https://nodejs.org/. Con este proceso también se instalará npm.

Para comprobar qué versión de Node.js instalaste, ejecuta el siguiente comando en el terminal:

node --version

Si quieres instalar la versión más reciente de Firebase CLI, ejecuta el siguiente comando en el terminal:

npm install -g firebase-tools

Para conectar el equipo local a la cuenta de Firebase y obtener acceso a los proyectos de Firebase, ejecuta el siguiente comando:

firebase login

Luego, deberás inicializar Cloud Functions.

Si aún no inicializaste el proyecto de Firebase con Hosting, ejecuta el siguiente comando dentro del directorio del proyecto. Cuando se te solicite, elige inicializar Hosting y Cloud Functions.

firebase init

Sin embargo, si tienes un proyecto de Firebase existente con Hosting, ejecuta el siguiente comando dentro del directorio del proyecto para inicializar solo Cloud Functions.

firebase init functions

Crea una función HTTP en el sitio de Hosting

Abre /functions/index.js en el editor que prefieras y reemplaza su contenido con lo siguiente. Este código crea una función HTTP llamada bigben.

const functions = require('firebase-functions');

exports.bigben = functions.https.onRequest((req, res) => {
  const hours = (new Date().getHours() % 12) + 1 // London is UTC + 1hr;
  res.status(200).send(`<!doctype html>
    <head>
      <title>Time</title>
    </head>
    <body>
      ${'BONG '.repeat(hours)}
    </body>
  </html>`);
});

Dirige solicitudes de Hosting a la función

Gracias a las reglas de reescritura, puedes dirigir solicitudes que coincidan con patrones específicos a un mismo destino. Por ejemplo, a fin de dirigir todas las solicitudes desde la página /bigben en el sitio de Hosting para que ejecuten la función bigben, abre firebase.json y agrega la siguiente configuración de rewrite en la sección hosting.

{
  "hosting": {
    "public": "public",

    // Add the following rewrites section *within* "hosting"
    "rewrites": [ {
      "source": "/bigben", "function": "bigben"
    } ]
  }
}

Ten en cuenta que Firebase Hosting está sujeto a un tiempo de espera de la solicitud de 60 segundos. Por lo tanto, aunque configures la función HTTP con un mayor tiempo de espera de la solicitud, seguirás recibiendo el código de estado 504 de HTTP (tiempo de espera de la solicitud agotado) si la función requiere más de 60 segundos para ejecutarse. Para admitir este tipo de contenido dinámico, se recomienda usar el entorno flexible de App Engine.

Visita la sección de hosting personalizado para obtener más detalles sobre las reglas de reescritura. También puedes obtener información sobre el orden de prioridad de las respuestas de varias configuraciones de Hosting.

Ejecuta contenido dinámico de manera local

Puedes entregar y ejecutar funciones de manera local con Firebase CLI. Esto te permite ver y probar tu proyecto de Firebase antes de implementarlo en producción.

Para usar esta función, asegúrate de que los SDK de firebase-tools y firebase-functions sean las versiones más recientes disponibles. Para actualizar ambos, ejecuta los siguientes comandos en el directorio functions/ del proyecto:

npm install --save firebase-functions@latest
npm install -g firebase-tools

Para procesar tu proyecto de Firebase de manera local, ejecuta el siguiente comando desde el directorio de tu proyecto. Este comando emulará hosting y functions en URL alojadas de manera local.

firebase serve
Cuando usas Cloud Functions a fin de generar contenido dinámico para Firebase Hosting, firebase serve, se utilizan tus funciones locales de HTTP como proxies en el hosting de forma predeterminada. Si quieres conocer más opciones de configuración para Firebase Hosting y Cloud Functions, consulta la Referencia de Firebase CLI.

Si usas variables de configuración de funciones personalizadas, ejecuta el siguiente comando en el directorio functions de tu proyecto antes de ejecutar firebase serve:

firebase functions:config:get > .runtimeconfig.json

Sin embargo, si usas Windows PowerShell, reemplaza el comando anterior por este:

firebase functions:config:get | ac .runtimeconfig.json

Implementa

Después de crear una función y configurar las reglas de reescritura, implementa el proyecto de Firebase. Para ello, ejecuta el siguiente comando en la terminal:

firebase deploy

Después de la implementación, notarás que se puede acceder de manera normal a la función a través de una URL, por ejemplo:

https://us-central1-your-project-id.cloudfunctions.net/bigben

Todo el tráfico del sitio de Firebase Hosting que coincida con la ruta especificada y las reglas de reescritura se dirigirá a la función apropiada.

Prueba la muestra

Una vez que todo esté implementado, puedes ir a /bigben en el sitio de Firebase Hosting para verlo en acción.

https://your-project-id.firebaseapp.com/bigben

Uso de cookies

Por lo general, cuando usas Firebase Hosting en conjunto con Cloud Functions, se separan las cookies de las solicitudes entrantes. Esto es necesario para permitir un comportamiento eficiente de la caché de CDN. Solo se permite que pase la cookie con el nombre especial __session a la ejecución de la función.

Cuando está presente, la cookie __session forma parte de la clave de caché de manera automática, lo que significa que es imposible que dos usuarios con cookies diferentes reciban la respuesta en la caché del otro. Únicamente debes usar la cookie __session si la función ofrece un contenido diferente según la autorización del usuario.

Administra el comportamiento de la caché

Firebase Hosting usa una potente CDN global para que el sitio sea lo más rápido posible. Se almacena en la caché el contenido estático de Firebase Hosting hasta que implementes una nueva versión de este. No se almacenan en caché en la CDN de forma predeterminada las solicitudes controladas por una función dado que las funciones generan contenido dinámicamente. Puedes configurar el comportamiento de la caché para acelerar la app y reducir los costos de ejecución de la función.

Configura Cache-Control

La herramienta principal que usarás para administrar la caché es el encabezado Cache-Control. Si lo configuras, puedes comunicarles tanto al navegador como a la CDN cuánto tiempo se debe almacenar el contenido en caché. En la función, configura Cache-Control de la siguiente manera:

res.set('Cache-Control', 'public, max-age=300, s-maxage=600');

El encabezado anterior tiene tres funciones:

  • Asigna el valor public a la caché. Eso significa que se puede almacenar el contenido en los servidores intermedios (en nuestro caso, la CDN). Según la configuración predeterminada, Cache-Control tiene el valor private, lo que significa que solo el navegador del usuario puede almacenarlo en caché.
  • Le indica al navegador por cuántos segundos puede almacenar el contenido con max-age. En el ejemplo anterior, le decimos al navegador que almacene en caché durante cinco minutos.
  • Le indica a la CDN durante cuántos segundos puede almacenar el contenido en caché con s-maxage. En el ejemplo anterior, le decimos a la CDN que almacene en caché durante diez minutos.

En el caso de max-age, configura su valor en función de la cantidad de tiempo máxima durante la cual deseas que los usuarios reciban contenido inactivo. Si una página cambia cada pocos segundos, max-age debe tener un valor menor. Sin embargo, se puede almacenar otro tipo de contenido sin problemas en caché durante horas, días o incluso meses.

Puedes obtener más información sobre el encabezado Cache-Control en la Red de desarrolladores de Mozilla.

¿Cuándo se sirve el contenido almacenado en caché?

Si configuraste un encabezado Cache-Control público, se almacenará el contenido en caché en la CDN según:

  • el nombre de host
  • la ruta de acceso
  • la cadena de consulta
  • el contenido de los encabezados especificados en Vary

El encabezado Vary es la manera de señalar qué partes de la solicitud son importantes para determinar la respuesta. Por lo general, no debes preocuparte de esto. Firebase Hosting garantiza automáticamente que se configure un encabezado Vary apropiado en la respuesta para las situaciones comunes. Esto incluye asegurarse de que cualquier cookie de sesión o encabezado de autorización que uses sea parte de la clave de caché, a fin de evitar filtraciones de contenido accidentales.

En algunos casos prácticos avanzados, es posible que necesites otros encabezados para la caché. En esas situaciones, solo tienes que configurar el encabezado Vary en la respuesta:

res.set('Vary', 'Accept-Encoding, X-My-Custom-Header');

Con esta configuración, si hay dos solicitudes idénticas, pero con distintos encabezados X-My-Custom-Header, se almacenan en caché por separado.

Enviar comentarios sobre...

Si necesitas ayuda, visita nuestra página de asistencia.