Migración de Extensión a Base de Código de Functions y Paquete npm
Resumen
Migra una Extensión de Firebase a uno de los siguientes formatos:
- Una base de código local de Cloud Functions (
functions/src/para integración en la aplicación). - Un paquete npm publicable (paquete open-source reutilizable que exporta funciones V2).
Aprovecha las funciones nativas de Cloud Functions (IAM declarativo, Configuración Parametrizada, Hooks del Ciclo de Vida del SDK) y moderniza los desencadenadores de 1.ª Generación a 2.ª Generación utilizando el Compatibilidad de Desestructuración (Destructuring Compatibility Shim).
Flujos de Migración Objetivo
-
Objetivo A: Base de Código Local de Functions (Integración en la Aplicación del Usuario Final)
- Salida: Código en
functions/src/. Configuración en.env. - Despliegue:
firebase deploy --only functions.
- Salida: Código en
-
Objetivo B: Paquete npm Publicable / Paquete Compartible
- Salida: Paquete npm reutilizable que exporta funciones V2.
- Configuración:
package.jsonespecificando el mapaexports,engines: { "node": ">=22" }, ypeerDependencies: { "firebase-functions": ">=6.0.0" }. - Uso: Los consumidores instalan el paquete y re-exportan las funciones en
index.ts(export * from "<nombre-del-paquete>").
Reglas y Restricciones Principales
1. IAM y APIs Declarativos (Sin Sobrecarga Local)
Usa declaraciones nativas del SDK en lugar de scripts gcloud manuales o instrucciones de la consola:
- Usa
requiresRole("roles/...")para los permisos IAM de GCP necesarios. - Usa
requiresAPI("service.googleapis.com", "Descripción")para las APIs de Google.
2. Restricción de Acceso Global a Parámetros
- Nunca llames a
.value()en el ámbito de carga del módulo de nivel superior. - Inicializa las instancias del SDK global dentro de
onInit()o getters perezosos:import { defineString } from "firebase-functions/params"; import { onInit } from "firebase-functions/v2"; const dataset = defineString("DATASET_ID"); let client: BigQuery; onInit(() => { client = new BigQuery({ datasetId: dataset.value() }); });
3. Concurrencia y Paridad de Costos en V2
V2 habilita la concurrencia (hasta 80 solicitudes). Para preservar el precio de concurrencia única de V1, establece cpu: "gcf_gen1".
Ejecución de la Migración Paso a Paso
Paso 1: Inventario de Recursos de la Extensión
extension.yaml:params→defineString,defineInt,defineBoolean,defineSecret.apis→requiresAPI(...).roles→requiresRole(...).lifecycleEvents→afterFirstDeployyafterRedeploy.resources→ Actualiza los desencadenadores de 1.ª Generación a 2.ª Generación (onDocumentWritten,onTaskDispatched,onRequest).
- Archivos y Scripts: Conserva las devDependencies, el framework de pruebas (
jest) y los scripts de prueba.
Paso 2: Configurar package.json
- Establece
name: "<nombre-del-paquete>",engines: { "node": ">=22" }. - Establece
peerDependencies:"peerDependencies": { "firebase-admin": "^11.0.0 || ^12.0.0", "firebase-functions": ">=6.0.0" } - Configura el mapa
exportsapuntando a declaraciones ESM/CommonJS y TypeScript (lib/index.js,lib/index.d.ts).
Paso 3: Actualizar Desencadenadores de V1 a V2
- Firestore: Usa
onDocumentWrittendefirebase-functions/v2/firestore. - Tareas: Usa
onTaskDispatcheddefirebase-functions/v2/tasks. EliminaEXT_INSTANCE_IDal encolar tareas. - HTTP: Usa
onRequestdefirebase-functions/v2/https. - Aplica el Compatibilidad de Desestructuración (
{ change, context },{ snapshot, context }) donde los manejadores heredados de 1.ª Generación esperan(change, context).
Paso 4: Convertir Eventos del Ciclo de Vida
Asigna los eventos del ciclo de vida de la extensión a los hooks del ciclo de vida del SDK en src/index.ts:
onInstall→afterFirstDeploy({ task: { function: "initTask" } })onUpdate/onConfigure→afterRedeploy({ task: { function: "setupTask" } })
Paso 5: README del Paquete e Instrucciones de Exportación
Genera README.md que contenga:
- Instrucciones de instalación (
npm install). - Fragmento de re-exportación (
export * from "<nombre-del-paquete>"). - Tabla de referencia de configuración parametrizada
.env. - Tabla de comparación de cambios (Extensión vs Paquete).
Recordatorio: NUNCA ejecutes npm publish.