Administrar funciones


Puede implementar, eliminar y modificar funciones mediante los comandos de Firebase CLI o configurando opciones de tiempo de ejecución en el código fuente de sus funciones.

Implementar funciones

Para implementar funciones, ejecute este comando de Firebase CLI:

firebase deploy --only functions

De forma predeterminada, Firebase CLI implementa todas las funciones dentro de su fuente al mismo tiempo. Si su proyecto contiene más de 5 funciones, le recomendamos que utilice el indicador --only con nombres de funciones específicos para implementar solo las funciones que ha editado. La implementación de funciones específicas de esta manera acelera el proceso de implementación y le ayuda a evitar toparse con cuotas de implementación. Por ejemplo:

firebase deploy --only functions:addMessage,functions:makeUppercase

Al implementar una gran cantidad de funciones, es posible que supere la cuota estándar y reciba mensajes de error HTTP 429 o 500. Para resolver esto, implemente funciones en grupos de 10 o menos.

Consulte la referencia de Firebase CLI para obtener la lista completa de comandos disponibles.

De forma predeterminada, Firebase CLI busca el código fuente en la carpeta functions/ . Si lo prefiere, puede organizar funciones en bases de código o en múltiples conjuntos de archivos.

Eliminar funciones

Puede eliminar funciones implementadas previamente de estas maneras:

  • explícitamente en Firebase CLI con functions:delete
  • explícitamente en la consola de Google Cloud .
  • implícitamente eliminando la función del código fuente antes de la implementación.

Todas las operaciones de eliminación le solicitan que confirme antes de eliminar la función de producción.

La eliminación explícita de funciones en Firebase CLI admite múltiples argumentos, así como grupos de funciones, y le permite especificar una función que se ejecuta en una región en particular. Además, puede anular el mensaje de confirmación.

# Delete all functions that match the specified name in all regions.
firebase functions:delete myFunction
# Delete a specified function running in a specific region.
firebase functions:delete myFunction --region us-east-1
# Delete more than one function
firebase functions:delete myFunction myOtherFunction
# Delete a specified functions group.
firebase functions:delete groupA
# Bypass the confirmation prompt.
firebase functions:delete myFunction --force

Con la eliminación implícita de funciones, firebase deploy analiza su fuente y elimina de producción cualquier función que se haya eliminado del archivo.

Modificar el nombre, la región o el activador de una función

Si está cambiando el nombre o cambiando las regiones o el activador de funciones que manejan el tráfico de producción, siga los pasos de esta sección para evitar perder eventos durante la modificación. Antes de seguir estos pasos, primero asegúrese de que su función sea idempotente , ya que tanto la versión nueva como la versión anterior de su función se ejecutarán al mismo tiempo durante el cambio.

Cambiar el nombre de una función

Para cambiar el nombre de una función, cree una nueva versión renombrada de la función en su fuente y luego ejecute dos comandos de implementación separados. El primer comando implementa la función recién nombrada y el segundo comando elimina la versión implementada anteriormente. Por ejemplo, si tiene una función de Node.js llamada webhook que le gustaría cambiar a webhookNew , revise el código de la siguiente manera:

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

exports.webhook = functions.https.onRequest((req, res) => {
    res.send("Hello");
});

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

exports.webhookNew = functions.https.onRequest((req, res) => {
    res.send("Hello");
});

Luego ejecute los siguientes comandos para implementar la nueva función:

# Deploy new function called webhookNew
firebase deploy --only functions:webhookNew

# Wait until deployment is done; now both webhookNew and webhook are running

# Delete webhook
firebase functions:delete webhook

Cambiar la región o regiones de una función

Si está cambiando las regiones especificadas para una función que maneja el tráfico de producción, puede evitar la pérdida de eventos realizando estos pasos en orden:

  1. Cambie el nombre de la función y cambie su región o regiones según lo desee.
  2. Implemente la función renombrada, lo que da como resultado la ejecución temporal del mismo código en ambos conjuntos de regiones.
  3. Eliminar la función anterior.

Por ejemplo, si tiene una función llamada webhook que se encuentra actualmente en la región de funciones predeterminada de us-central1 y desea migrarla a asia-northeast1 , primero debe modificar su código fuente para cambiar el nombre de la función y revisar la región. .

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

exports.webhook = functions
    .https.onRequest((req, res) => {
            res.send("Hello");
    });

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

exports.webhookAsia = functions
    .region('asia-northeast1')
    .https.onRequest((req, res) => {
            res.send("Hello");
    });

Luego implemente ejecutando:

firebase deploy --only functions:webhookAsia

Ahora se están ejecutando dos funciones idénticas: webhook se ejecuta en us-central1 y webhookAsia se ejecuta en asia-northeast1 .

Luego, elimine webhook :

firebase functions:delete webhook

Ahora solo hay una función: webhookAsia , que se ejecuta en asia-northeast1 .

Cambiar el tipo de disparador de una función

A medida que desarrollas tu implementación de Cloud Functions para Firebase con el tiempo, es posible que necesites cambiar el tipo de activador de una función por varios motivos. Por ejemplo, es posible que quieras cambiar de un tipo de evento de Firebase Realtime Database o Cloud Firestore a otro tipo.

No es posible cambiar el tipo de evento de una función simplemente cambiando el código fuente y ejecutando firebase deploy . Para evitar errores, cambie el tipo de activación de una función mediante este procedimiento:

  1. Modifique el código fuente para incluir una nueva función con el tipo de activador deseado.
  2. Implemente la función, lo que da como resultado la ejecución temporal de las funciones nuevas y antiguas.
  3. Elimina explícitamente la función anterior de producción mediante Firebase CLI.

Por ejemplo, si tenía una función de Node.js llamada objectChanged que tiene el tipo de evento onChange heredado y desea cambiarla a onFinalize , primero cambie el nombre de la función y edítela para que tenga el tipo de evento onFinalize .

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

exports.objectChanged = functions.storage.object().onChange((object) => {
    return console.log('File name is: ', object.name);
});

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

exports.objectFinalized = functions.storage.object().onFinalize((object) => {
    return console.log('File name is: ', object.name);
});

Luego ejecute los siguientes comandos para crear la nueva función primero, antes de eliminar la función anterior:

# Create new function objectFinalized
firebase deploy --only functions:objectFinalized

# Wait until deployment is done; now both objectChanged and objectFinalized are running

# Delete objectChanged
firebase functions:delete objectChanged

Establecer opciones de tiempo de ejecución

Cloud Functions para Firebase le permite seleccionar opciones de tiempo de ejecución, como la versión de tiempo de ejecución de Node.js y el tiempo de espera por función, la asignación de memoria y las instancias de función mínima/máxima.

Como práctica recomendada, estas opciones (excepto la versión Node.js) deben configurarse en un objeto de configuración dentro del código de la función. Este objeto RuntimeOptions es la fuente de verdad para las opciones de tiempo de ejecución de tu función y anulará las opciones configuradas mediante cualquier otro método (como a través de la consola de Google Cloud o la CLI de gcloud).

Si su flujo de trabajo de desarrollo implica configurar manualmente las opciones de tiempo de ejecución a través de la consola de Google Cloud o la CLI de gcloud y no desea que estos valores se anulen en cada implementación, configure la opción preserveExternalChanges en true . Con esta opción configurada en true , Firebase fusiona las opciones de tiempo de ejecución configuradas en tu código con la configuración de la versión actualmente implementada de tu función con la siguiente prioridad:

  1. La opción está configurada en el código de funciones: anular cambios externos.
  2. La opción está configurada en RESET_VALUE en el código de funciones: anular los cambios externos con el valor predeterminado.
  3. La opción no está configurada en el código de funciones, pero sí en la función implementada actualmente: use la opción especificada en la función implementada.

No se recomienda el uso de la opción preserveExternalChanges: true para la mayoría de los escenarios porque su código ya no será la fuente completa de verdad para las opciones de tiempo de ejecución de sus funciones. Si lo usas, consulta la consola de Google Cloud o usa la CLI de gcloud para ver la configuración completa de una función.

Establecer la versión de Node.js

El SDK de Firebase para Cloud Functions permite una selección del tiempo de ejecución de Node.js. Puede optar por ejecutar todas las funciones de un proyecto exclusivamente en el entorno de ejecución correspondiente a una de estas versiones compatibles de Node.js:

  • Node.js 20 (vista previa)
  • Nodo.js 18
  • Nodo.js 16
  • Nodo.js 14

Para configurar la versión de Node.js:

Puede configurar la versión en el campo engines en el archivo package.json que se creó en su directorio functions/ durante la inicialización. Por ejemplo, para usar solo la versión 18, edite esta línea en package.json :

  "engines": {"node": "18"}

Si está utilizando el administrador de paquetes Yarn o tiene otros requisitos específicos para el campo engines , puede configurar el tiempo de ejecución para Firebase SDK para Cloud Functions en firebase.json :

  {
    "functions": {
      "runtime": "nodejs18" // or nodejs14, nodejs16 or nodejs20
    }
  }

La CLI usa el valor establecido en firebase.json con preferencia a cualquier valor o rango que establezca por separado en package.json .

Actualice su tiempo de ejecución de Node.js

Para actualizar su tiempo de ejecución de Node.js:

  1. Asegúrese de que su proyecto esté en el plan de precios de Blaze .
  2. Asegúrese de estar utilizando Firebase CLI v11.18.0 o posterior.
  3. Cambie el valor engines en el archivo package.json que se creó en su directorio functions/ durante la inicialización. Por ejemplo, si está actualizando de la versión 16 a la versión 18, la entrada debería verse así: "engines": {"node": "18"}
  4. Opcionalmente, pruebe sus cambios usando Firebase Local Emulator Suite .
  5. Vuelva a implementar todas las funciones.

Controlar el comportamiento de escalado

De forma predeterminada, Cloud Functions para Firebase escala la cantidad de instancias en ejecución según la cantidad de solicitudes entrantes, pudiendo reducirla a cero instancias en momentos de tráfico reducido. Sin embargo, si su aplicación requiere una latencia reducida y desea limitar la cantidad de inicios en frío, puede cambiar este comportamiento predeterminado especificando una cantidad mínima de instancias de contenedor que se mantendrán activas y listas para atender solicitudes.

De manera similar, puede establecer un número máximo para limitar el escalado de instancias en respuesta a solicitudes entrantes. Utilice esta configuración como una forma de controlar sus costos o limitar la cantidad de conexiones a un servicio de respaldo, como una base de datos.

Reducir el número de arranques en frío

Para establecer un número mínimo de instancias para una función en el código fuente, utilice el método runWith . Este método acepta un objeto JSON conforme a la interfaz RuntimeOptions , que define el valor de minInstances . Por ejemplo, esta función establece un mínimo de 5 instancias para mantenerse caliente:

exports.getAutocompleteResponse = functions
    .runWith({
      // Keep 5 instances warm for this latency-critical function
      minInstances: 5,
    })
    .https.onCall((data, context) => {
      // Autocomplete a user's search term
    });

Aquí hay algunas cosas a considerar al establecer un valor para minInstances :

  • Si Cloud Functions para Firebase escala tu aplicación por encima de tu configuración minInstances , experimentarás un inicio en frío para cada instancia que supere ese umbral.
  • Los arranques en frío tienen el efecto más grave en aplicaciones con mucho tráfico. Si su aplicación tiene un tráfico elevado y establece un valor minInstances lo suficientemente alto como para que los inicios en frío se reduzcan con cada aumento de tráfico, verá una latencia significativamente reducida. Para aplicaciones con tráfico constante, no es probable que los arranques en frío afecten gravemente al rendimiento.
  • Establecer instancias mínimas puede tener sentido para entornos de producción, pero normalmente debe evitarse en entornos de prueba. Para escalar a cero en su proyecto de prueba pero aún reducir los inicios en frío en su proyecto de producción, puede configurar minInstances según la variable de entorno FIREBASE_CONFIG :

    // Get Firebase project id from `FIREBASE_CONFIG` environment variable
    const envProjectId = JSON.parse(process.env.FIREBASE_CONFIG).projectId;
    
    exports.renderProfilePage = functions
        .runWith({
          // Keep 5 instances warm for this latency-critical function
          // in production only. Default to 0 for test projects.
          minInstances: envProjectId === "my-production-project" ? 5 : 0,
        })
        .https.onRequest((req, res) => {
          // render some html
        });
    

Limitar el número máximo de instancias de una función

Para establecer el número máximo de instancias en el código fuente de la función, utilice el método runWith . Este método acepta un objeto JSON conforme a la interfaz RuntimeOptions , que define valores para maxInstances . Por ejemplo, esta función establece un límite de 100 instancias para no saturar una base de datos heredada hipotética:

exports.mirrorOrdersToLegacyDatabase = functions
    .runWith({
      // Legacy database only supports 100 simultaneous connections
      maxInstances: 100,
    })
    .firestore.document("orders/{orderId}")
    .onWrite((change, context) => {
      // Connect to legacy database
    });

Si una función HTTP se amplía hasta el límite de maxInstances , las nuevas solicitudes se ponen en cola durante 30 segundos y luego se rechazan con un código de respuesta de 429 Too Many Requests si no hay ninguna instancia disponible para entonces.

Para obtener más información sobre las mejores prácticas para usar la configuración de instancias máximas, consulte estas mejores prácticas para usar maxInstances .

Establecer tiempo de espera y asignación de memoria

En algunos casos, sus funciones pueden tener requisitos especiales para un valor de tiempo de espera prolongado o una gran asignación de memoria. Puede establecer estos valores en Google Cloud Console o en el código fuente de la función (solo Firebase).

Para configurar la asignación de memoria y el tiempo de espera en el código fuente de funciones, use el parámetro runWith introducido en Firebase SDK para Cloud Functions 2.0.0. Esta opción de tiempo de ejecución acepta un objeto JSON conforme a la interfaz RuntimeOptions , que define valores para timeoutSeconds y memory . Por ejemplo, esta función de almacenamiento utiliza 1 GB de memoria y se agota después de 300 segundos:

exports.convertLargeFile = functions
    .runWith({
      // Ensure the function has enough memory and time
      // to process large files
      timeoutSeconds: 300,
      memory: "1GB",
    })
    .storage.object()
    .onFinalize((object) => {
      // Do some complicated things that take a lot of memory and time
    });

El valor máximo de timeoutSeconds es 540 o 9 minutos. La cantidad de memoria otorgada a una función corresponde a la CPU asignada para la función, como se detalla en esta lista de valores válidos para memory :

  • 128MB - 200 MHz
  • 256MB - 400 MHz
  • 512MB - 800 MHz
  • 1GB - 1,4 GHz
  • 2GB - 2,4 GHz
  • 4GB - 4,8 GHz
  • 8GB : 4,8 GHz

Para configurar la asignación de memoria y el tiempo de espera en la consola de Google Cloud:

  1. En la consola de Google Google Cloud, seleccione Funciones de nube en el menú de la izquierda.
  2. Seleccione una función haciendo clic en su nombre en la lista de funciones.
  3. Haga clic en el icono Editar en el menú superior.
  4. Seleccione una asignación de memoria en el menú desplegable denominado Memoria asignada .
  5. Haga clic en Más para mostrar las opciones avanzadas e ingrese una cantidad de segundos en el cuadro de texto Tiempo de espera .
  6. Haga clic en Guardar para actualizar la función.