Comece agora: escrever, testar e implantar as primeiras funções


Para começar a usar o Cloud Functions, siga as etapas deste tutorial, que começa com as tarefas de configuração necessárias e avança para a criação, teste e implantação de duas funções relacionadas:

  • Uma função "adicionar mensagem" que expõe um URL que aceita um valor de texto e o grava no Cloud Firestore.
  • Uma função "mudar para letras maiúsculas" que é acionada em uma gravação do Cloud Firestore e transforma o texto em letras maiúsculas.

Confira o exemplo de código completo contendo as funções:

Node.js

// The Cloud Functions for Firebase SDK to create Cloud Functions and triggers.
const {logger} = require("firebase-functions");
const {onRequest} = require("firebase-functions/v2/https");
const {onDocumentCreated} = require("firebase-functions/v2/firestore");

// The Firebase Admin SDK to access Firestore.
const {initializeApp} = require("firebase-admin/app");
const {getFirestore} = require("firebase-admin/firestore");

initializeApp();

// Take the text parameter passed to this HTTP endpoint and insert it into
// Firestore under the path /messages/:documentId/original
exports.addmessage = onRequest(async (req, res) => {
  // Grab the text parameter.
  const original = req.query.text;
  // Push the new message into Firestore using the Firebase Admin SDK.
  const writeResult = await getFirestore()
      .collection("messages")
      .add({original: original});
  // Send back a message that we've successfully written the message
  res.json({result: `Message with ID: ${writeResult.id} added.`});
});

// Listens for new messages added to /messages/:documentId/original
// and saves an uppercased version of the message
// to /messages/:documentId/uppercase
exports.makeuppercase = onDocumentCreated("/messages/{documentId}", (event) => {
  // Grab the current value of what was written to Firestore.
  const original = event.data.data().original;

  // Access the parameter `{documentId}` with `event.params`
  logger.log("Uppercasing", event.params.documentId, original);

  const uppercase = original.toUpperCase();

  // You must return a Promise when performing
  // asynchronous tasks inside a function
  // such as writing to Firestore.
  // Setting an 'uppercase' field in Firestore document returns a Promise.
  return event.data.ref.set({uppercase}, {merge: true});
});

Python (pré-lançamento)

# The Cloud Functions for Firebase SDK to create Cloud Functions and set up triggers.
from firebase_functions import firestore_fn, https_fn

# The Firebase Admin SDK to access Cloud Firestore.
from firebase_admin import initialize_app, firestore
import google.cloud.firestore

app = initialize_app()


@https_fn.on_request()
def addmessage(req: https_fn.Request) -> https_fn.Response:
    """Take the text parameter passed to this HTTP endpoint and insert it into
    a new document in the messages collection."""
    # Grab the text parameter.
    original = req.args.get("text")
    if original is None:
        return https_fn.Response("No text parameter provided", status=400)

    firestore_client: google.cloud.firestore.Client = firestore.client()

    # Push the new message into Cloud Firestore using the Firebase Admin SDK.
    _, doc_ref = firestore_client.collection("messages").add(
        {"original": original}
    )

    # Send back a message that we've successfully written the message
    return https_fn.Response(f"Message with ID {doc_ref.id} added.")




@firestore_fn.on_document_created(document="messages/{pushId}")
def makeuppercase(
    event: firestore_fn.Event[firestore_fn.DocumentSnapshot | None],
) -> None:
    """Listens for new documents to be added to /messages. If the document has
    an "original" field, creates an "uppercase" field containg the contents of
    "original" in upper case."""

    # Get the value of "original" if it exists.
    if event.data is None:
        return
    try:
        original = event.data.get("original")
    except KeyError:
        # No "original" field, so do nothing.
        return

    # Set the "uppercase" field.
    print(f"Uppercasing {event.params['pushId']}: {original}")
    upper = original.upper()
    event.data.reference.update({"uppercase": upper})


Sobre este tutorial

Um dos motivos por termos escolhido o Cloud Firestore e as funções acionadas por HTTP para esta amostra é porque esses gatilhos em segundo plano podem ser testados completamente com o Pacote de emuladores locais do Firebase. Esse conjunto de ferramentas também oferece suporte a gatilhos chamáveis do Realtime Database, PubSub, Auth e HTTP. Outros tipos de gatilhos em segundo plano, como os da Configuração remota e do TestLab, podem ser testados de modo interativo usando conjuntos de ferramentas não descritos nesta página.

Veja nas seções a seguir os detalhes das etapas necessárias para criar, testar e implantar a amostra.

Criar um projeto do Firebase

  1. No Console do Firebase, clique em Adicionar projeto.

    • Para adicionar recursos do Firebase a um projeto do Google Cloud existente, digite o nome dele ou selecione-o no menu suspenso.

    • Para criar um novo projeto, digite o nome dele. Também é possível editar o ID do projeto exibido abaixo do nome dele.

  2. Se solicitado, leia e aceite os Termos do Firebase.

  3. Clique em Continuar.

  4. (Opcional) Configure o Google Analytics para o projeto e tenha uma experiência ideal quando usar qualquer um destes produtos do Firebase:

    Selecione uma conta do Google Analytics ou crie uma nova.

    Se você decidir criar uma nova conta, selecione seu local de relatórios do Analytics e aceite as configurações de compartilhamento de dados e os termos do Google Analytics relacionados ao seu projeto.

  5. Clique em Criar projeto (ou Adicionar Firebase, se você estiver usando um projeto do Google Cloud).

O Firebase provisiona recursos automaticamente para seu projeto. Quando o processo for concluído, você será direcionado para a página de visão geral do seu projeto no Console do Firebase.

Configurar o ambiente e a CLI do Firebase

Node.js

Você vai precisar de um ambiente do Node.js para criar funções, além da CLI do Firebase para implantá-las no ambiente de execução do Cloud Functions. Para instalar o Node.js e o npm, recomendamos o Node Version Manager.

Depois de instalar o Node.js e o npm, use o método que preferir para instalar a CLI do Firebase. Para instalar a CLI pelo npm, use:

npm install -g firebase-tools

Essa ação instala o comando firebase disponível globalmente. Se o comando falhar, talvez seja necessário alterar as permissões do NPM (em inglês). Para atualizar para a versão mais recente, de firebase-tools execute novamente o mesmo comando.

Python (pré-lançamento)

Você vai precisar de um ambiente do Python para criar funções, além da CLI do Firebase para implantar funções no ambiente de execução do Cloud Functions. Recomendamos o uso de venv para isolar as dependências. As versões 3.10 e 3.11 do Python são compatíveis.

Depois de instalar o Python, instale a CLI do Firebase usando o método de sua preferência.

Inicializar seu projeto

Ao inicializar o SDK do Firebase para Cloud Functions, você cria um projeto vazio contendo dependências e alguns códigos de amostra mínimos. Se estiver usando Node.js, você vai poder escolher TypeScript ou JavaScript para compor funções. Para este tutorial, também será necessário inicializar o Cloud Firestore.

Para inicializar seu projeto, faça o seguinte:

  1. Execute o firebase login para fazer login pelo navegador e autenticar a CLI do Firebase.
  2. Vá para o diretório do projeto do Firebase.
  3. Execute firebase init firestore. Neste tutorial, aceite os valores padrão quando solicitado para regras e arquivos de índice do Firestore. Se ainda não usou o Cloud Firestore neste projeto, selecione um modo e local iniciais para o Firestore, como descrito em Introdução ao Cloud Firestore.
  4. Execute firebase init functions. Conforme solicitação da CLI, selecione uma base de código que já exista ou inicie e atribua um nome a uma nova base. Para quem está começando, uma única base de código no local padrão é suficiente. Conforme você for implementando mais vezes, organize as funções em bases de código.
  5. A CLI oferece as seguintes opções de suporte de idioma:

    • JavaScript
    • TypeScript
    • Python

    Para este tutorial, selecione JavaScript ou Python. Para criação no TypeScript, consulte Como escrever funções com TypeScript.

  6. A CLI oferece uma opção para instalar dependências. Se você quiser gerenciar as dependências de outra forma, basta recusar.

Depois que esses comandos forem concluídos, a estrutura do seu projeto terá a seguinte aparência:

Node.js

myproject
+- .firebaserc    # Hidden file that helps you quickly switch between
|                 # projects with `firebase use`
|
+- firebase.json  # Describes properties for your project
|
+- functions/     # Directory containing all your functions code
      |
      +- .eslintrc.json  # Optional file containing rules for JavaScript linting.
      |
      +- package.json  # npm package file describing your Cloud Functions code
      |
      +- index.js      # Main source file for your Cloud Functions code
      |
      +- node_modules/ # Directory where your dependencies (declared in
                        # package.json) are installed

Para Node.js, o arquivo package.json criado durante a inicialização contém uma chave importante: "engines": {"node": "18"}. Ela especifica sua versão do Node.js para escrever e implantar funções. É possível selecionar outras versões com suporte.

Python (pré-lançamento)

myproject
+- .firebaserc    # Hidden file that helps you quickly switch between
|                 # projects with `firebase use`
|
+- firebase.json  # Describes properties for your project
|
+- functions/     # Directory containing all your functions code
      |
      +- main.py      # Main source file for your Cloud Functions code
      |
      +- requirements.txt  #  List of the project's modules and packages 
      |
      +- venv/ # Directory where your dependencies are installed

Importar os módulos necessários e inicializar um aplicativo

Depois de concluir as tarefas de configuração, abra o diretório de origem e comece a adicionar o código conforme descrito nas seções a seguir. Para essa amostra, seu projeto precisa importar os módulos do Cloud Functions e do SDK Admin. Adicione linhas como as seguintes ao seu arquivo de origem:

Node.js

// The Cloud Functions for Firebase SDK to create Cloud Functions and triggers.
const {logger} = require("firebase-functions");
const {onRequest} = require("firebase-functions/v2/https");
const {onDocumentCreated} = require("firebase-functions/v2/firestore");

// The Firebase Admin SDK to access Firestore.
const {initializeApp} = require("firebase-admin/app");
const {getFirestore} = require("firebase-admin/firestore");

initializeApp();

Python (pré-lançamento)

# The Cloud Functions for Firebase SDK to create Cloud Functions and set up triggers.
from firebase_functions import firestore_fn, https_fn

# The Firebase Admin SDK to access Cloud Firestore.
from firebase_admin import initialize_app, firestore
import google.cloud.firestore

app = initialize_app()

Essas linhas carregam os módulos necessários e inicializam uma instância do app admin em que as alterações do Cloud Firestore podem ser feitas. Os locais onde o suporte ao SDK Admin está disponível, assim como para o FCM, o Authentication e o Firebase Realtime Database, oferecem acesso a uma maneira eficiente de integrar o Firebase usando o Cloud Functions.

Quando você inicializa o projeto, a CLI do Firebase instala automaticamente o SDK Admin do Firebase e o SDK do Firebase para os módulos do Cloud Functions. Para mais informações sobre como adicionar bibliotecas de terceiros ao seu projeto, consulte Gerenciar dependências.

Adicionar a função "adicionar mensagem"

Para a função "adicionar mensagem", adicione estas linhas ao seu arquivo de origem:

Node.js

// Take the text parameter passed to this HTTP endpoint and insert it into
// Firestore under the path /messages/:documentId/original
exports.addmessage = onRequest(async (req, res) => {
  // Grab the text parameter.
  const original = req.query.text;
  // Push the new message into Firestore using the Firebase Admin SDK.
  const writeResult = await getFirestore()
      .collection("messages")
      .add({original: original});
  // Send back a message that we've successfully written the message
  res.json({result: `Message with ID: ${writeResult.id} added.`});
});

Python (pré-lançamento)

@https_fn.on_request()
def addmessage(req: https_fn.Request) -> https_fn.Response:
    """Take the text parameter passed to this HTTP endpoint and insert it into
    a new document in the messages collection."""
    # Grab the text parameter.
    original = req.args.get("text")
    if original is None:
        return https_fn.Response("No text parameter provided", status=400)

    firestore_client: google.cloud.firestore.Client = firestore.client()

    # Push the new message into Cloud Firestore using the Firebase Admin SDK.
    _, doc_ref = firestore_client.collection("messages").add(
        {"original": original}
    )

    # Send back a message that we've successfully written the message
    return https_fn.Response(f"Message with ID {doc_ref.id} added.")


A função "adicionar mensagem" é um endpoint HTTP. Qualquer solicitação para o endpoint resulta na transmissão de objetos de solicitação e de resposta ao gerenciador de solicitações da sua plataforma (onRequest() ou on_request).

Como as funções HTTP são síncronas (semelhantes às funções chamáveis), é necessário enviar uma resposta o mais rápido possível e adiar o trabalho usando o Cloud Firestore. A função HTTP "adicionar mensagem" transmite um valor de texto para o endpoint HTTP e o insere no banco de dados no caminho /messages/:documentId/original.

Adicionar a função "mudar para letras maiúsculas"

Para a função "mudar para letras maiúsculas", adicione estas linhas ao arquivo de origem:

Node.js

// Listens for new messages added to /messages/:documentId/original
// and saves an uppercased version of the message
// to /messages/:documentId/uppercase
exports.makeuppercase = onDocumentCreated("/messages/{documentId}", (event) => {
  // Grab the current value of what was written to Firestore.
  const original = event.data.data().original;

  // Access the parameter `{documentId}` with `event.params`
  logger.log("Uppercasing", event.params.documentId, original);

  const uppercase = original.toUpperCase();

  // You must return a Promise when performing
  // asynchronous tasks inside a function
  // such as writing to Firestore.
  // Setting an 'uppercase' field in Firestore document returns a Promise.
  return event.data.ref.set({uppercase}, {merge: true});
});

Python (pré-lançamento)

@firestore_fn.on_document_created(document="messages/{pushId}")
def makeuppercase(
    event: firestore_fn.Event[firestore_fn.DocumentSnapshot | None],
) -> None:
    """Listens for new documents to be added to /messages. If the document has
    an "original" field, creates an "uppercase" field containg the contents of
    "original" in upper case."""

    # Get the value of "original" if it exists.
    if event.data is None:
        return
    try:
        original = event.data.get("original")
    except KeyError:
        # No "original" field, so do nothing.
        return

    # Set the "uppercase" field.
    print(f"Uppercasing {event.params['pushId']}: {original}")
    upper = original.upper()
    event.data.reference.update({"uppercase": upper})


A função "mudar para letras maiúsculas" é executada quando o Cloud Firestore é gravado, definindo o documento a ser detectado. Para melhorar o desempenho, seja o mais específico possível.

As chaves, como {documentId}, envolvem "parâmetros", caracteres curinga que expõem os dados correspondidos na callback. O Cloud Firestore aciona a callback sempre que novas mensagens são adicionadas.

No Node.js, as funções orientadas a eventos, como os eventos do Cloud Firestore, são assíncronas. A função de callback precisa retornar um valor null, um objeto ou uma promessa (em inglês). Se não retornar nada, a função expira, sinaliza um erro e é repetida. Consulte Sincronização, dessincronização e promessas.

Emular a execução de suas funções

Com o Pacote de emuladores locais do Firebase, é possível criar e testar apps na máquina local em vez de implantar em um projeto do Firebase. O teste local durante o desenvolvimento é altamente recomendado, já que ele reduz o risco de erros de codificação que podem gerar custos em um ambiente de produção, como um loop infinito.

Para emular suas funções, siga estas etapas:

  1. Execute firebase emulators:start e verifique a saída do URL da IU do Pacote de emuladores. O padrão é localhost:4.000, mas pode estar hospedado em uma porta diferente na sua máquina. Digite esse URL no navegador para abrir a IU do Pacote de emuladores.

  2. Verifique a saída do comando firebase emulators:start para o URL da função HTTP. Ele será semelhante a http://localhost:5001/MY_PROJECT/us-central1/addMessage, porém:

    1. MY_PROJECT será substituído pelo ID do projeto;
    2. a porta pode ser diferente na máquina local.
  3. Adicione a string de consulta ?text=uppercaseme ao final do URL da função. A aparência será semalhente a esta: http://localhost:5001/MY_PROJECT/us-central1/addMessage?text=uppercaseme. Se quiser, você pode alterar a mensagem "uppercaseme" para uma mensagem personalizada.

  4. Crie uma nova mensagem abrindo o URL em uma nova guia do navegador.

  5. Veja os efeitos das funções na IU do Pacote do emulador.

    1. Na guia Registros, você verá novos registros indicando que as funções HTTP foram executadas com sucesso:

      i functions: Beginning execution of "addMessage"

      i functions: Beginning execution of "makeUppercase"

    2. Na guia Firestore, você verá um documento que contém a mensagem original e a versão em letra maiúscula da mensagem. Se originalmente era "uppercaseme", ela aparecerá como "UPPERCASEME".

Implantar funções em um ambiente de produção

Quando as funções estiverem funcionando da maneira correta no emulador, você poderá continuar a implantá-las, testá-las e executá-las no ambiente de produção. Para implantar na produção, seu projeto precisa estar no plano de preços Blaze. Consulte Preços do Cloud Functions.

Para concluir o tutorial, implante e execute as funções.

  1. Execute este comando para implantar as funções:

     firebase deploy --only functions
     

    Depois de executar o comando, a Firebase CLI produz o URL para quaisquer pontos de extremidade da função HTTP. No seu terminal, aparecerá uma linha como esta:

    Function URL (addMessage): https://us-central1-MY_PROJECT.cloudfunctions.net/addMessage
    

    O URL contém o código do seu projeto, bem como uma região para a função HTTP. Ainda que você não precise se preocupar com isso agora, algumas funções HTTP de produção precisam especificar um local para minimizar a latência da rede.

    Se você encontrar erros de acesso, como "Não foi possível autorizar o acesso ao projeto", tente verificar o alias do seu projeto.

  2. Use o resultado do URL da CLI para adicionar um parâmetro de consulta de texto e abra-o em um navegador:

    https://us-central1-MY_PROJECT.cloudfunctions.net/addMessage?text=uppercasemetoo
    

    A função executa e redireciona o navegador para o Console do Firebase no local do banco de dados em que a string de texto está armazenada. Esse evento de gravação aciona a função "mudar para letras maiúsculas", que grava uma versão da string em letra maiúscula.

Depois de implantar e executar funções, é possível ver os registros no Console do Google Cloud. Se você precisar excluir funções em desenvolvimento ou produção, use a CLI do Firebase.

Na produção, convém otimizar o desempenho da função e controlar os custos definindo os números mínimo e máximo de instâncias a serem executadas. Consulte Controlar o comportamento de escalonamento para mais informações sobre essas opções de ambiente de execução.

Próximas etapas

Saiba mais nesta documentação sobre como gerenciar funções do Cloud Functions e como lidar com todos os tipos de eventos compatíveis com ele.

Para saber mais sobre o Cloud Functions, você também pode fazer o seguinte: