Las aplicaciones que actualmente utilizan funciones de 1.ª generación deberían considerar migrar a la 2.ª generación siguiendo las instrucciones de esta guía. Las funciones de segunda generación utilizan Cloud Run para proporcionar un mejor rendimiento, una mejor configuración, una mejor supervisión y más.
Los ejemplos de esta página suponen que está utilizando JavaScript con módulos CommonJS ( require
importaciones de estilos), pero los mismos principios se aplican a JavaScript con ESM ( import … from
importaciones de estilos) y TypeScript.
El proceso migratorio
Las funciones de 1.ª y 2.ª generación pueden coexistir una al lado de la otra en el mismo archivo. Esto permite una fácil migración pieza por pieza, a medida que esté listo. Recomendamos migrar una función a la vez, realizar pruebas y verificaciones antes de continuar.
Verifique las versiones de Firebase CLI y firebase-function
Asegúrate de utilizar al menos la versión 12.00
de Firebase CLI y la versión 4.3.0
de firebase-functions
. Cualquier versión más nueva admitirá tanto la 2.ª generación como la 1.ª generación.
Actualizar importaciones
Las funciones de segunda generación se importan desde el subpaquete v2
en el SDK firebase-functions
. Esta ruta de importación diferente es todo lo que Firebase CLI necesita para determinar si implementar su código de función como una función de primera o segunda generación.
El subpaquete v2
es modular y recomendamos importar solo el módulo específico que necesite.
Antes: 1.ª generación
const functions = require("firebase-functions");
Después: 2da generación
// explicitly import each trigger
const {onRequest} = require("firebase-functions/v2/https");
const {onDocumentCreated} = require("firebase-functions/v2/firestore");
Actualizar definiciones de desencadenadores
Dado que el SDK de segunda generación favorece las importaciones modulares, actualice las definiciones de los activadores para reflejar las importaciones modificadas del paso anterior.
Los argumentos pasados a las devoluciones de llamada para algunos desencadenantes han cambiado. En este ejemplo, tenga en cuenta que los argumentos de la devolución de llamada onDocumentCreated
se han consolidado en un único objeto event
. Además, algunos disparadores tienen nuevas características de configuración convenientes, como la opción cors
del disparador onRequest
.
Antes: 1.ª generación
const functions = require("firebase-functions");
exports.date = functions.https.onRequest((req, res) => {
// ...
});
exports.uppercase = functions.firestore
.document("my-collection/{docId}")
.onCreate((change, context) => {
// ...
});
Después: 2da generación
const {onRequest} = require("firebase-functions/v2/https");
const {onDocumentCreated} = require("firebase-functions/v2/firestore");
exports.date = onRequest({cors: true}, (req, res) => {
// ...
});
exports.uppercase = onDocumentCreated("my-collection/{docId}", (event) => {
/* ... */
});
Usar configuración parametrizada
Las funciones de segunda generación eliminan el soporte para functions.config
en favor de una interfaz más segura para definir parámetros de configuración de forma declarativa dentro de su código base. Con el nuevo módulo params
, la CLI bloquea la implementación a menos que todos los parámetros tengan un valor válido, lo que garantiza que no se implemente una función sin configuración.
Migrar al subpaquete params
Si ha estado utilizando la configuración del entorno con functions.config
, puede migrar su configuración existente a una configuración parametrizada .
Antes: 1.ª generación
const functions = require("firebase-functions");
exports.date = functions.https.onRequest((req, res) => {
const date = new Date();
const formattedDate =
date.toLocaleDateString(functions.config().dateformat);
// ...
});
Después: 2da generación
const {onRequest} = require("firebase-functions/v2/https");
const {defineString} = require("firebase-functions/params");
const dateFormat = defineString("DATE_FORMAT");
exports.date = onRequest((req, res) => {
const date = new Date();
const formattedDate = date.toLocaleDateString(dateFormat.value());
// ...
});
Establecer valores de parámetros
La primera vez que realiza la implementación, Firebase CLI solicita todos los valores de los parámetros y los guarda en un archivo dotenv. Para exportar sus valores de funciones.config, ejecute firebase functions:config:export
.
Para mayor seguridad, también puede especificar tipos de parámetros y reglas de validación .
Caso especial: claves API
El módulo params
se integra con Cloud Secret Manager, que proporciona un control de acceso detallado a valores confidenciales como claves API. Consulte los parámetros secretos para obtener más información.
Antes: 1.ª generación
const functions = require("firebase-functions");
exports.getQuote = functions.https.onRequest(async (req, res) => {
const quote = await fetchMotivationalQuote(functions.config().apiKey);
// ...
});
Después: 2da generación
const {onRequest} = require("firebase-functions/v2/https");
const {defineSecret} = require("firebase-functions/params");
// Define the secret parameter
const apiKey = defineSecret("API_KEY");
exports.getQuote = onRequest(
// make the secret available to this function
{ secrets: [apiKey] },
async (req, res) => {
// retrieve the value of the secret
const quote = await fetchMotivationalQuote(apiKey.value());
// ...
}
);
Establecer opciones de tiempo de ejecución
La configuración de las opciones de tiempo de ejecución ha cambiado entre la 1.ª y la 2.ª generación. La segunda generación también agrega una nueva capacidad para configurar opciones para todas las funciones.
Antes: 1.ª generación
const functions = require("firebase-functions");
exports.date = functions
.runWith({
// Keep 5 instances warm for this latency-critical function
minInstances: 5,
})
// locate function closest to users
.region("asia-northeast1")
.https.onRequest((req, res) => {
// ...
});
exports.uppercase = functions
// locate function closest to users and database
.region("asia-northeast1")
.firestore.document("my-collection/{docId}")
.onCreate((change, context) => {
// ...
});
Después: 2da generación
const {onRequest} = require("firebase-functions/v2/https");
const {onDocumentCreated} = require("firebase-functions/v2/firestore");
const {setGlobalOptions} = require("firebase-functions/v2");
// locate all functions closest to users
setGlobalOptions({ region: "asia-northeast1" });
exports.date = onRequest({
// Keep 5 instances warm for this latency-critical function
minInstances: 5,
}, (req, res) => {
// ...
});
exports.uppercase = onDocumentCreated("my-collection/{docId}", (event) => {
/* ... */
});
Usar concurrencia
Una ventaja significativa de las funciones de segunda generación es la capacidad de una única instancia de función para atender más de una solicitud a la vez. Esto puede reducir drásticamente la cantidad de arranques en frío que experimentan los usuarios finales. De forma predeterminada, la simultaneidad está establecida en 80, pero puede establecerla en cualquier valor entre 1 y 1000:
const {onRequest} = require("firebase-functions/v2/https");
exports.date = onRequest({
// set concurrency value
concurrency: 500
},
(req, res) => {
// ...
});
El ajuste de la concurrencia puede mejorar el rendimiento y reducir el costo de las funciones. Obtenga más información sobre la simultaneidad en Permitir solicitudes simultáneas .
Auditar el uso de variables globales
Las funciones de primera generación escritas sin tener en cuenta la simultaneidad pueden utilizar variables globales que se configuran y leen en cada solicitud. Cuando la simultaneidad está habilitada y una sola instancia comienza a manejar múltiples solicitudes a la vez, esto puede introducir errores en su función ya que las solicitudes simultáneas comienzan a configurar y leer variables globales simultáneamente.
Mientras actualiza, puede configurar la CPU de su función en gcf_gen1
y establecer concurrency
en 1 para restaurar el comportamiento de primera generación:
const {onRequest} = require("firebase-functions/v2/https");
exports.date = onRequest({
// TEMPORARY FIX: remove concurrency
cpu: "gcf_gen1",
concurrency: 1
},
(req, res) => {
// ...
});
Sin embargo, esto no se recomienda como solución a largo plazo, ya que pierde las ventajas de rendimiento de las funciones de segunda generación. En su lugar, audite el uso de variables globales en sus funciones y elimine estas configuraciones temporales cuando esté listo.
Migrar el tráfico a las nuevas funciones de segunda generación
Al igual que cuando se cambia la región o el tipo de activador de una función , deberá darle un nuevo nombre a la función de segunda generación y migrar lentamente el tráfico hacia ella.
No es posible actualizar una función de 1.ª a 2.ª generación con el mismo nombre y ejecutar firebase deploy
. Al hacerlo, se producirá el error:
Upgrading from GCFv1 to GCFv2 is not yet supported. Please delete your old function or wait for this feature to be ready.
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. Por ejemplo, si tiene una función de 1.ª generación que responde a eventos de escritura en Firestore, asegúrese de que responder a una escritura dos veces, una vez por la función de 1.ª generación y otra por la función de 2.ª generación, en respuesta a esos eventos deje su aplicación en un estado consistente.
- Cambie el nombre de la función en su código de funciones. Por ejemplo, cambie el nombre
resizeImage
aresizeImageSecondGen
. - Implemente la función de modo que se estén ejecutando tanto la función original de 1.ª generación como la función de 2.ª generación.
- En el caso de activadores invocables, de cola de tareas y HTTP, comience a señalar a todos los clientes a la función de segunda generación actualizando el código del cliente con el nombre o la URL de la función de segunda generación.
- Con activadores en segundo plano, las funciones de 1.ª y 2.ª generación responderán a cada evento inmediatamente después de la implementación.
- Cuando se haya migrado todo el tráfico, elimine la función de 1.ª generación mediante el comando
firebase functions:delete
Firebase CLI.- Opcionalmente, cambie el nombre de la función de 2.ª generación para que coincida con el nombre de la función de 1.ª generación.