Os aplicativos que atualmente usam funções de 1ª geração devem considerar a migração para a 2ª geração seguindo as instruções deste guia. As funções de segunda geração usam o Cloud Run para fornecer melhor desempenho, melhor configuração, melhor monitoramento e muito mais.
Os exemplos nesta página pressupõem que você esteja usando JavaScript com módulos CommonJS ( require
importações de estilo), mas os mesmos princípios se aplicam a JavaScript com ESM ( import … from
importações de estilo) e TypeScript.
O processo de migração
As funções de 1ª e 2ª geração podem coexistir lado a lado no mesmo arquivo. Isso permite uma migração fácil, peça por peça, quando estiver pronto. Recomendamos migrar uma função por vez, realizando testes e verificações antes de continuar.
Verifique as versões do Firebase CLI e firebase-function
Certifique-se de usar pelo menos Firebase CLI versão 12.00
e firebase-functions
versão 4.3.0
. Qualquer versão mais recente suportará a 2ª geração e também a 1ª geração.
Atualizar importações
As funções de 2ª geração são importadas do subpacote v2
no firebase-functions
SDK. Esse caminho de importação diferente é tudo o que a CLI do Firebase precisa para determinar se deve implantar seu código de função como uma função de primeira ou segunda geração.
O subpacote v2
é modular e recomendamos importar apenas o módulo específico necessário.
Antes: 1ª geração
const functions = require("firebase-functions");
Depois: 2ª geração
// explicitly import each trigger
const {onRequest} = require("firebase-functions/v2/https");
const {onDocumentCreated} = require("firebase-functions/v2/firestore");
Atualizar definições de gatilho
Como o SDK de 2ª geração favorece importações modulares, atualize as definições do gatilho para refletir as importações alteradas da etapa anterior.
Os argumentos passados para retornos de chamada de alguns gatilhos foram alterados. Neste exemplo, observe que os argumentos para o retorno de chamada onDocumentCreated
foram consolidados em um único objeto event
. Além disso, alguns gatilhos possuem novos recursos de configuração convenientes, como a opção cors
do gatilho onRequest
.
Antes: 1ª geração
const functions = require("firebase-functions");
exports.date = functions.https.onRequest((req, res) => {
// ...
});
exports.uppercase = functions.firestore
.document("my-collection/{docId}")
.onCreate((change, context) => {
// ...
});
Depois: 2ª geração
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 configuração parametrizada
As funções de 2ª geração abandonam o suporte para functions.config
em favor de uma interface mais segura para definir parâmetros de configuração declarativamente dentro de sua base de código. Com o novo módulo params
, a CLI bloqueia a implantação, a menos que todos os parâmetros tenham um valor válido, garantindo que uma função não seja implantada com configuração ausente.
Migrar para o subpacote params
Se você estiver usando a configuração de ambiente com functions.config
, poderá migrar sua configuração existente para a configuração parametrizada .
Antes: 1ª geração
const functions = require("firebase-functions");
exports.date = functions.https.onRequest((req, res) => {
const date = new Date();
const formattedDate =
date.toLocaleDateString(functions.config().dateformat);
// ...
});
Depois: 2ª geração
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());
// ...
});
Definir valores de parâmetros
Na primeira vez que você implanta, a CLI do Firebase solicita todos os valores dos parâmetros e salva os valores em um arquivo dotenv. Para exportar seus valores de functions.config, execute firebase functions:config:export
.
Para segurança adicional, você também pode especificar tipos de parâmetros e regras de validação .
Caso especial: chaves de API
O módulo params
integra-se ao Cloud Secret Manager, que fornece controle de acesso refinado a valores confidenciais, como chaves de API. Consulte parâmetros secretos para obter mais informações.
Antes: 1ª geração
const functions = require("firebase-functions");
exports.getQuote = functions.https.onRequest(async (req, res) => {
const quote = await fetchMotivationalQuote(functions.config().apiKey);
// ...
});
Depois: 2ª geração
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());
// ...
}
);
Definir opções de tempo de execução
A configuração das opções de tempo de execução mudou entre a 1ª e a 2ª geração. A 2ª geração também adiciona um novo recurso para definir opções para todas as funções.
Antes: 1ª geração
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) => {
// ...
});
Depois: 2ª geração
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 simultaneidade
Uma vantagem significativa das funções de 2ª geração é a capacidade de uma única instância de função atender mais de uma solicitação ao mesmo tempo. Isso pode reduzir drasticamente o número de partidas a frio experimentadas pelos usuários finais. Por padrão, a simultaneidade é definida como 80, mas você pode defini-la como qualquer valor de 1 a 1000:
const {onRequest} = require("firebase-functions/v2/https");
exports.date = onRequest({
// set concurrency value
concurrency: 500
},
(req, res) => {
// ...
});
O ajuste da simultaneidade pode melhorar o desempenho e reduzir o custo das funções. Saiba mais sobre simultaneidade em Permitir solicitações simultâneas .
Auditar o uso de variáveis globais
Funções de 1ª geração escritas sem simultaneidade em mente podem usar variáveis globais que são definidas e lidas em cada solicitação. Quando a simultaneidade está habilitada e uma única instância começa a lidar com várias solicitações ao mesmo tempo, isso pode introduzir bugs em sua função, pois as solicitações simultâneas começam a configurar e ler variáveis globais simultaneamente.
Durante a atualização, você pode definir a CPU da sua função como gcf_gen1
e definir concurrency
como 1 para restaurar o comportamento da 1ª geração:
const {onRequest} = require("firebase-functions/v2/https");
exports.date = onRequest({
// TEMPORARY FIX: remove concurrency
cpu: "gcf_gen1",
concurrency: 1
},
(req, res) => {
// ...
});
No entanto, isto não é recomendado como uma solução a longo prazo, pois perde as vantagens de desempenho das funções de 2ª geração. Em vez disso, audite o uso de variáveis globais em suas funções e remova essas configurações temporárias quando estiver pronto.
Migre o tráfego para as novas funções de 2ª geração
Assim como ao alterar a região ou o tipo de gatilho de uma função , você precisará dar um novo nome à função de 2ª geração e migrar lentamente o tráfego para ela.
Não é possível atualizar uma função de 1ª para 2ª geração com o mesmo nome e executar firebase deploy
. Fazer isso resultará no erro:
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 essas etapas, primeiro certifique-se de que sua função seja idempotente , pois tanto a nova versão quanto a versão antiga de sua função estarão em execução ao mesmo tempo durante a alteração. Por exemplo, se você tiver uma função de 1ª geração que responde a eventos de gravação no Firestore, certifique-se de que responder a uma gravação duas vezes, uma vez pela função de 1ª geração e uma vez pela função de 2ª geração, em resposta a esses eventos deixe seu aplicativo em um estado de alerta. estado consistente.
- Renomeie a função no seu código de funções. Por exemplo, renomeie
resizeImage
pararesizeImageSecondGen
. - Implante a função, de modo que tanto a função original de 1ª geração quanto a função de 2ª geração estejam em execução.
- No caso de gatilhos chamáveis, fila de tarefas e HTTP, comece a apontar todos os clientes para a função de 2ª geração atualizando o código do cliente com o nome ou URL da função de 2ª geração.
- Com acionadores em segundo plano, as funções de 1ª e 2ª geração responderão a todos os eventos imediatamente após a implantação.
- Quando todo o tráfego for migrado, exclua a função de 1ª geração usando o comando
firebase functions:delete
da CLI do Firebase.- Opcionalmente, renomeie a função de 2ª geração para corresponder ao nome da função de 1ª geração.