Migrar as Extensões do Firebase para um kit de funções criado por você

Selecione o caminho de migração: Migrar para kits de funções no npm Migrar para um kit de funções criado por você

Se um editor não tiver criado um kit de substituição oficial distribuído no npm, este guia vai mostrar as etapas para bifurcar a extensão e configurá-la como um kit de funções local.

Verificar limitações de migração conhecidas

Antes de começar a migrar uma instância de extensão, verifique se a configuração usa algum dos seguintes recursos que exigem uma solução alternativa ou ainda não são compatíveis com kits de funções:

  • Repositórios personalizados do Docker e chaves do KMS exigem uma solução alternativa manual O Cloud Functions for Firebase não é compatível com parâmetros de sistema de substituição para configurar um repositório personalizado do Docker ou uma chave de criptografia gerenciada pelo cliente (chave do KMS). Se a extensão configurar um desses parâmetros, consulte a solução alternativa nas perguntas frequentes.

Antes de começar

É necessário configurar a CLI do Firebase e inicializar um projeto do Firebase. Ao usar a CLI, verifique se você está usando a versão >= 15.32.0 da firebase-tools, que tem os novos comandos de migração e kit de funções.

Permissões e papéis necessários da conta

Dependendo do que precisa ser criado e configurado pela CLI Firebase durante a migração, a conta que você está usando para autenticar com Firebase e Google Cloud precisa ter os seguintes papéis:

  • roles/firebaseextensions.editor
  • roles/cloudbuild.builds.editor
  • roles/artifactregistry.writer
  • roles/run.developer
  • roles/iam.serviceAccountUser
  • roles/iam.serviceAccountCreator
  • roles/cloudfunctions.admin (se você precisar fazer setIamPermissions para endpoints públicos)
  • roles/secretmanager.admin (se estiver usando secrets)
  • roles/serviceusage.serviceUsageAdmin (se você precisar ativar novas APIs)

Recomendamos usar uma conta que já tenha instalado extensões e implantado funções, já que a maioria dessas permissões já terá sido concedida. Se a conta de migração precisar de mais papéis, siga as instruções do IAM do Google Cloud para adicioná-los.

Fazer upgrade da instância de extensão para a versão mais recente

Você precisa atualizar sua extensão para a versão mais recente para minimizar a diferença entre a instância da extensão e o kit de substituição. Se a extensão não for atualizada, pode haver mudanças significativas e interruptivas entre a instância da extensão e a substituição do kit. A configuração exportada pode não corresponder ao que o kit espera devido a mudanças de parâmetros entre as versões.

Use uma das seguintes opções para atualizar a extensão, dependendo de onde ela foi instalada:

  • No console do Firebase
  • Na CLI do Firebase usando:
    • firebase ext:update <extension-instance-id> --project <project-id> firebase deploy --only extensions --project <project-id>

Se você pular essa etapa, a CLI vai solicitar que você faça upgrade ao exportar a configuração se a extensão não estiver na versão mais recente.

Criar uma bifurcação da extensão em um kit de funções local

Antes de começar a converter uma extensão em um kit de funções locais, verifique se o código-fonte da extensão está no projeto do Firebase. Para fazer isso, clone o repositório da extensão do GitHub, crie um diretório dentro da raiz do projeto Firebase e copie a pasta functions/ e o arquivo extension.yaml da extensão para ele:

mkdir -p path/to/kit
cp -r /path/to/extension-source/functions/* path/to/kit/
cp /path/to/extension-source/extension.yaml path/to/kit/.

Siga as etapas de 1 a 8 do guia de migração para publishers para migrar o código-fonte da extensão para uma função de 2ª geração. Depois, siga estas etapas:

Fazer com que o kit local seja compatível com a região da função exportada e os parâmetros avançados

Em um kit de funções local, a CLI Firebase não gera um arquivo index.ts para configurar o pacote e usá-lo com parâmetros de sistema migrados. Para usar a região da função e os parâmetros avançados que foram configurados para sua extensão, configure o arquivo index.ts para ler o formato exportado por firebase ext:export --mode functions em um arquivo de variável de ambiente.

Especificamente, no arquivo index.ts de nível superior que exporta suas funções, defina um parâmetro para FUNCTION_DEFAULT_REGION e chame setGlobalOptions com variáveis de ambiente do formato EXT_MIGRATED_SYSTEM_<GLOBAL_OPTION>, semelhante ao modelo index-kit-migration.ts usado pela CLI:

import { setGlobalOptions } from "firebase-functions";
import { MemoryOption, VpcEgressSetting, IngressSetting } from "firebase-functions/v2/options";
import { defineString } from "firebase-functions/params";

export const regionParam = defineString("FUNCTION_DEFAULT_REGION", {
  input: { text: { nonEmpty: true } },
  description: "Global default region where functions should be deployed. Can be overridden per-function.",
});

setGlobalOptions({
  region: regionParam,
  memory: (process.env.EXT_MIGRATED_SYSTEM_MEMORY as MemoryOption) ?? undefined,
  timeoutSeconds: process.env.EXT_MIGRATED_SYSTEM_TIMEOUTSECONDS
    ? Number(process.env.EXT_MIGRATED_SYSTEM_TIMEOUTSECONDS)
    : undefined,
  vpcConnectorEgressSettings:
    process.env.EXT_MIGRATED_SYSTEM_VPCCONNECTOREGRESSSETTINGS &&
    process.env.EXT_MIGRATED_SYSTEM_VPCCONNECTOREGRESSSETTINGS !== "VPC_CONNECTOR_EGRESS_SETTINGS_UNSPECIFIED"
      ? (process.env.EXT_MIGRATED_SYSTEM_VPCCONNECTOREGRESSSETTINGS as VpcEgressSetting)
      : undefined,
  vpcConnector: process.env.EXT_MIGRATED_SYSTEM_VPCCONNECTOR ?? undefined,
  maxInstances: process.env.EXT_MIGRATED_SYSTEM_MAXINSTANCES
    ? Number(process.env.EXT_MIGRATED_SYSTEM_MAXINSTANCES)
    : undefined,
  minInstances: process.env.EXT_MIGRATED_SYSTEM_MININSTANCES
    ? Number(process.env.EXT_MIGRATED_SYSTEM_MININSTANCES)
    : undefined,
  ingressSettings: (process.env.EXT_MIGRATED_SYSTEM_INGRESSSETTINGS as IngressSetting) ?? undefined,
  // Parses a comma-separated string of key:value pairs into a key-value object
  // (for example, "key1:value1,key2:value2" -> { key1: "value1", key2: "value2" }).
  labels: process.env.EXT_MIGRATED_SYSTEM_LABELS
    ? process.env.EXT_MIGRATED_SYSTEM_LABELS.split(",").reduce<Record<string, string> | undefined>(
        (acc, curr) => {
          const [key, value] = curr.split(":");
          const trimmedKey = key?.trim();
          const trimmedValue = value?.trim();
          if (!trimmedKey || !trimmedValue) {
            return acc;
          }
          acc = acc ?? {};
          acc[trimmedKey] = trimmedValue;
          return acc;
        },
        undefined,
      )
    : undefined,
});

// Re-export all functions so the Firebase CLI can deploy them
export * from "./your-functions";

Teste o kit antes da migração

Agora você tem um kit de funções local que, quando implantado, se comporta de maneira idêntica a uma nova instalação da sua extensão. A próxima etapa é verificar e corrigir os problemas introduzidos acidentalmente ao longo do caminho antes de migrar as instâncias de extensão de produção para ele.

Primeiro, adicione seu fork como um kit local, configure-o e implante-o em um projeto de teste. Os kits de funções locais precisam estar no projeto do Firebase. Portanto, se o repositório de extensões clonado estiver fora do projeto do Firebase, mova-o para o diretório do projeto. Em seguida, execute o seguinte comando de instalação para instalá-lo como um kit local:

firebase functions:kits:install --directory <path-to-your-fork> --project <test-project-id>

Esse comando orienta você na escolha de um ID de kit, um ID de instância e uma configuração para sua primeira instância de teste. Em seguida, ele modifica o arquivo firebase.json para registrar um kit local que aponta para o diretório bifurcado, com configurações para cada instância armazenada em um arquivo .env em function-kits/<kit-id>/config-<instance-id>.

Implante o kit local em um projeto de teste com os recursos adequados para testar o comportamento dele. Se você já tiver um projeto de teste configurado para testar sua extensão, execute o seguinte comando:

firebase deploy --only functions:<kit-instance-id> --project <test-project-id>

Exemplo prático: transmitir do Cloud Firestore para o BigQuery (firestore-bigquery-export)

Verifique a sincronização de ponta a ponta do Cloud Firestore com o BigQuery:

  1. Na página Cloud Firestore do console do Firebase, crie a coleção definida como COLLECTION_PATH (users), se ela ainda não existir.
  2. Crie um documento chamado bigquery-mirror-test contendo campos com quaisquer valores.
  3. Na página BigQuery do console do Google Cloud, consulte a tabela de registro de alterações bruto. Ele precisa conter uma única linha que registre a criação do documento:

    SELECT * FROM `PROJECT_ID.analytics.users_raw_changelog`
    
  4. Consulte a visualização mais recente, que deve retornar o evento de mudança mais recente para o único documento presente (bigquery-mirror-test):

    SELECT * FROM `PROJECT_ID.analytics.users_raw_latest`
    
  5. Exclua o documento bigquery-mirror-test em Cloud Firestore. Ele desaparece da visualização mais recente, e um evento DELETE é anexado à tabela de registro de alterações bruto.

    É possível inspecionar o histórico completo de um único documento com:

    SELECT *
       FROM `PROJECT_ID.analytics.users_raw_changelog`
       WHERE document_name = "bigquery-mirror-test"
       ORDER BY timestamp ASC
    

Diferenças em relação ao teste da extensão:

  • O gatilho é implantado como kit-<kit-instance-id>-fsexportbigquery, não ext-<instanceId>-fsexportbigquery. Procure esse nome no painel e nos registros do Cloud Functions.
  • Seu código é executado no Firebase Local Emulator Suite como funções padrão. É possível definir valores de parâmetro para uso no emulador com .env.local. Também é possível fazer testes de unidade no código usando o SDK firebase-functions-test, conforme descrito em Testes de unidade de Cloud Functions.
  • O provisionamento não é mais controlado pelo ambiente de execução de extensões. Se a tabela de registro de alterações estiver ausente após a implantação, execute novamente a tarefa de configuração manualmente: firebase functions:lifecycle:run afterFirstDeploy <kit-instance-id>. A tarefa é idempotente, então executá-la novamente reconcilia o conjunto de dados, a tabela e as visualizações.
  • Os valores dos parâmetros vêm de .env, e não do formulário de instalação. Portanto, as novas execuções de firebase deploy não são interativas depois que .env é concluído.

(Opcional) Limpar os testes

Se quiser remover essa instância de teste após o teste, desinstale-a:

firebase functions:kits:uninstall --instance <kit-instance-id> --project <test-project-id>

Isso exclui todos os recursos de nuvem criados pela implantação do kit e remove a configuração da instância. Se você tiver apenas uma instância do kit, isso também vai remover a entrada do kit de firebase.json. Ele não exclui o diretório do código-fonte local. Ao instalar o kit para a migração de produção, é possível escolher um ID de kit novamente.

Migrar de extensões para o kit local

Agora que o kit local foi testado, é possível migrar a instância da extensão implantada em tempo real.

1. Instalar a instância do kit de funções de substituição

Instale o kit de funções local, transmitindo --no-configure para pular a configuração manual, de modo que a próxima etapa possa exportar a configuração de extensão atual diretamente para essa instância do kit:

firebase functions:kits:install --no-configure --directory <path-to-your-fork> --project <project-id>

2. Configure a instância do kit de funções de forma idêntica à extensão

É necessário personalizar essa instância do kit com uma configuração idêntica à da extensão que ela está substituindo. É possível exportar a configuração da instância de extensão para um arquivo .env, que armazena dados de configuração de parâmetros, variáveis de ambiente e referências secretas para todos os Cloud Functions, incluindo kits. Para exportá-la diretamente para o arquivo de configuração do kit, execute:

firebase ext:export --mode functions --instance <extension-instance-id> --kit-instance <kit-instance-id> --project <project-id>

No final desta etapa, as informações de configuração dessa instância são armazenadas em um arquivo .env específico do projeto no diretório de configuração da instância, como: function-kits/<kit-name>/config-<instance-id>/.env.<project-id>

3. Implantar e verificar a substituição do kit

Agora que o kit está instalado e disponível como um conjunto de funções, é possível implantar a substituição do kit. Os kits de funções funcionam como funções padrão, em que cada instância de kit atua como uma base de código separada para organizar suas funções. É possível implantar todas as funções ou apenas uma instância de kit específica. Ao migrar uma única instância de extensão, implante apenas essa instância do kit.

Se o kit usar novos parâmetros que não estavam presentes na instância da extensão migrada, a CLI Firebase vai solicitar esses parâmetros no início do processo de implantação. Isso não é esperado neste exemplo de uma extensão firestore-bigquery-export atualizada, mas muitos kits solicitam um novo parâmetro para qualquer origem de acionador de evento usada pelo kit. Como parte dessa migração, os kits atualizados usam funções de 2ª geração em que as extensões usavam funções de 1ª geração. Na 2ª geração, as funções estão localizadas perto das origens de eventos e são adicionadas como um parâmetro extra. Em atualizações futuras, se novos parâmetros forem adicionados, a CLI vai solicitar que você os informe na próxima implantação.

Exemplo prático:

firebase deploy --only functions:firestore-bigquery-export --project my-project

Saída:

=== Deploying to 'my-project'...
i  deploying functions
i  functions: Loaded environment variables from function-kits/firestore-bigquery-export/config-firestore-bigquery-export/.env.my-project
i  functions: ensuring required API bigquery.googleapis.com is enabled...
i  functions: ensuring required API cloudtasks.googleapis.com is enabled...
✔  functions: required APIs are enabled
i  functions: granting declarative IAM roles to managed service account:
   - BigQuery Data Editor
   - BigQuery User
   - Cloud Datastore User
   - Eventarc Event Receiver
   - roles/run.invoker
✔  functions: successfully granted IAM roles
i  functions: creating Node.js 22 (2nd Gen) function kit-firestore-bigquery-export-fsexportbigquery(us-central1)...
i  functions: creating Node.js 22 (2nd Gen) function kit-firestore-bigquery-export-initBigQuerySync(us-central1)...
i  functions: creating Node.js 22 (2nd Gen) function kit-firestore-bigquery-export-setupBigQuerySync(us-central1)...
✔  functions[kit-firestore-bigquery-export-fsexportbigquery(us-central1)] Successful create operation.
✔  functions[kit-firestore-bigquery-export-initBigQuerySync(us-central1)] Successful create operation.
✔  functions[kit-firestore-bigquery-export-setupBigQuerySync(us-central1)] Successful create operation.
i  functions: Executing afterFirstDeploy lifecycle hook targeting: kit-firestore-bigquery-export-initBigQuerySync...
✔  functions: Successfully queued task for lifecycle hook kit-firestore-bigquery-export-initBigQuerySync in queue projects/my-project/locations/us-central1/queues/kit-firestore-bigquery-export-initBigQuerySync.
✔  Deploy complete!

Para verificar se o firebase deploy do kit não teve erros, confira os registros de implantação para ver se algum gancho de ciclo de vida foi acionado. Extensões populares, como Stream Cloud Firestore to BigQuery, usam hooks de ciclo de vida. Confira um exemplo de como um hook de ciclo de vida aparece quando é acionado:

i  functions: Executing afterFirstDeploy lifecycle hook targeting: kit-firestore-bigquery-export-initBigQuerySync...
✔  functions: Successfully queued task for lifecycle hook kit-firestore-bigquery-export-initBigQuerySync in queue projects/my-project/locations/europe-west1/queues/kit-firestore-bigquery-export-initBigQuerySync.
i  functions: View logs for afterFirstDeploy at: https://console.cloud.google.com/logs/query;query=resource.type%3D%22cloud_run_revision%22%0Aresource.labels.service_name%3D%22kit-firestore-bigquery-export--initbigquerysync%22%0Aresource.labels.location%3D%22europe-west1%22;project=my-project

Essas mensagens de registro confirmam o seguinte:

  • Um hook de ciclo de vida foi encontrado e executado.
  • Uma tarefa foi colocada na fila de tarefas associada ao hook de ciclo de vida.
  • Um link para o Cloud Logging foi fornecido para que você possa validar se a tarefa foi concluída sem erros.

Siga o link de registros para o console do Google Cloud para validar que não há erros nos registros e que o evento da fila de tarefas foi processado com sucesso. Se o evento de ciclo de vida não tiver sido executado, será possível acioná-lo novamente executando:

firebase functions:lifecycle:run <hook-name> <codebase>

Se você estiver implantando uma instância do kit de funções pela primeira vez, execute:

firebase functions:lifecycle:run afterFirstDeploy <kit-instance-id>

Se, a qualquer momento durante a validação, você decidir interromper ou desfazer essa migração, desinstale o kit usando as instruções em Desinstalar a extensão.

Depois de verificar se a implantação inicial do kit de funções foi concluída, é necessário validar se a funcionalidade do kit está funcionando como esperado. Como a extensão em si ainda está em execução, você precisa ter cuidado para que o que está verificando não seja apenas que uma das duas funcionou, já que a extensão funcionou e vai continuar funcionando.

Se o processamento não for alterado e você não encontrar resultados duplicados da extensão e do kit, a melhor opção é examinar diretamente os registros do kit depois de acionar a funcionalidade dele.

Exemplo prático: transmitir Cloud Firestore para BigQuery

Com a extensão Stream Cloud Firestore to BigQuery, as gravações na tabela de registro de alterações bruto (*_raw_changelog) e na tabela de visualização mais recente (*_raw_latest) serão desduplicadas se o mesmo evento for entregue ao kit e à extensão. Portanto, não é possível usar a presença de linhas ou linhas duplicadas no BigQuery para validar se o kit está funcionando.

É possível ver os registros de funções logo após gravar na coleção do Firestore usando firebase functions:logs e procurar uma entrada de registro que indique que uma gravação foi processada com sucesso. Para este kit com o ID de instância padrão de firestore-bigquery-export, seria assim:

2026-09-25T19:52:46.328612Z I kit-firestore-bigquery-export-fsexportbigquery: Started execution of extension
2026-09-25T19:52:46.328644Z I kit-firestore-bigquery-export-fsexportbigquery: {"message":"Firestore event received by onDocumentWritten trigger","document_name":"projects/extensions-eventarc-testing/databases/(default)/documents/exported-messages/cmGP6XLyksqGdw2OgTOq","operation":0,"event_id":"9f59a2a4-1a5e-4c41-a32d-561e3c734502"}
2026-09-25T19:52:46.616064Z I kit-firestore-bigquery-export-fsexportbigquery: Completed execution of extension
2026-09-2

Se você tiver muitos registros, poderá filtrar para uma função específica do kit usando o seguinte comando:

firebase functions:log --only <function name>

Para encontrar os nomes de funções específicos de uma instância de kit, use o seguinte comando:

firebase functions:list | grep kit-<kit instance id>

Para este exemplo:

firebase functions:list | grep kit-firestore-bigquery-export
│ kit-firestore-bigquery-export-fsexportbigquery  │ v2      │ google.cloud.firestore.document.v1.written                    │
│ kit-firestore-bigquery-export-initBigQuerySync  │ v2      │ taskQueue                                                     │
│ kit-firestore-bigquery-export-setupBigQuerySync │ v2      │ taskQueue                                                     │
│ kit-firestore-bigquery-export-syncBigQuery      │ v2      │ taskQueue                                                     │

4. Desinstalar a extensão

Depois de verificar o kit de funções implantado, desinstale a extensão para não duplicar o comportamento dela uma vez para o kit e outra para a extensão. É possível desinstalar todas as extensões da CLI Firebase, independentemente de como foram instaladas, transmitindo a flag --immediate:

firebase ext:uninstall <extension-instance-id> --project <project-id> --immediate

Exemplo prático:

firebase ext:uninstall firestore-bigquery-export --project my-project --immediate

Saída:

i  extensions: uninstalling firestore-bigquery-export...
i  extensions: deleting extension instance resources in project my-project...
✔  extensions: successfully uninstalled firestore-bigquery-export

Migrações avançadas

É possível ter extensões em vários projetos do Firebase que você quer gerenciar com uma única base de código. Por exemplo, se você implantar a mesma infraestrutura em um ambiente testing e em um ambiente production, cada um com uma instância documents Cloud Firestore que você exporta para BigQuery, talvez tenha duas instâncias da extensão firestore-bigquery-export instaladas:

  • export-documents-testing
  • export-documents-production

Se você migrou essas duas instâncias de extensão para duas instâncias de kit de funções em uma única base de código ao trabalhar com a CLI Firebase e implantou usando firebase deploy --project testing e firebase deploy --project production, cada implantação criaria duas instâncias nos ambientes testing e production.

Em vez disso, substitua as duas instâncias de extensão por uma instância do kit de funções de firestore-bigquery-export implantada em vários projetos, em que cada projeto tem a própria configuração. O diretório de configuração da instância deve ser semelhante ao seguinte:

  • config-export-documents/
    • .env.testing
    • .env.production

Cada implantação em testing e production cria uma instância do kit com a configuração correspondente. Os comandos da CLI criam essa configuração, desde que você transmita a flag --project em cada invocação de ext:migrate ou functions:kits:install.

Exemplo prático:

firebase functions:kits:install --package @firebase-function-kits/firestore-bigquery-export --project testing --no-configure --template migration
✔ What would you like to name this kit? firestore-bigquery-export
✔ What would you like to name this instance? export-documents
✔  Wrote function-kits/firestore-bigquery-export/source/package.json
✔  Wrote function-kits/firestore-bigquery-export/source/tsconfig.json
✔  Wrote function-kits/firestore-bigquery-export/source/.gitignore
✔  Wrote function-kits/firestore-bigquery-export/source/src/index.ts
i  functions: Running npm install
✔  Wrote configuration info to firebase.json
✔  functions: Function kit firestore-bigquery-export successfully installed.
# This creates the export-documents instance with an empty .env.testing file
# for the testing project. Now populate it via export:
firebase ext:export --mode functions --instance export-documents-testing \
  --kit-instance export-documents --project testing

# Repeat the export for production into the same kit instance to create
# .env.production from the export-documents-prod instance:
firebase ext:export --mode functions --instance export-documents-prod \
  --kit-instance export-documents --project production

Agora você tem uma única instância de kit configurada para implantação nos projetos testing e production com as respectivas configurações. Se você criar uma instância no projeto testing e executar o comando functions:kits:install para o mesmo pacote no projeto production, será exibida a opção de reutilizar a instância configurada para testing ou instalar uma segunda instância.