Per iniziare: scrivi, testa ed esegui il deployment delle tue prime funzioni


Per iniziare a utilizzare Cloud Functions, prova a seguire questo tutorial, che inizia con le attività di configurazione richieste e prosegue con la creazione, il test e l'implementazione di due funzioni correlate:

  • Una funzione "aggiungi messaggio" che espone un URL che accetta un valore di testo e lo scrive in Cloud Firestore.
  • La formula "make up" (in maiuscolo) funzione che si attiva su una scrittura Cloud Firestore e trasforma il testo in maiuscolo.

Ecco il codice di esempio completo contenente le funzioni:

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

# 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})

Informazioni su questo tutorial

Per questo abbiamo scelto Cloud Firestore e funzioni attivate da HTTP il campione in parte perché questi fattori scatenanti in background possono essere testati tramite Firebase Local Emulator Suite. Questo set di strumenti supporta anche gli trigger chiamabili Realtime Database, Cloud Storage, PubSub, Auth e HTTP. Altri tipi di attivatori in background, come gli attivatori Remote Config e TestLab, possono essere testati in modo interattivo utilizzando set di strumenti non descritti in questa pagina.

Le sezioni seguenti di questo tutorial descrivono in dettaglio i passaggi necessari per compilare, testare e implementare il sample.

Crea un progetto Firebase

  1. Nella console Firebase, fai clic su Aggiungi progetto.

    • Per aggiungere risorse Firebase a un progetto Google Cloud esistente, inserisci il nome del progetto o selezionalo dal menu a discesa.

    • Per creare un nuovo progetto, inserisci il nome desiderato. Se vuoi, puoi anche modificare l'ID progetto visualizzato sotto il nome del progetto.

  2. Se richiesto, leggi e accetta i Termini di Firebase.

  3. Fai clic su Continua.

  4. (Facoltativo) Configura Google Analytics per il tuo progetto, che ti consente per un'esperienza ottimale con i seguenti prodotti Firebase:

    Seleziona un account Google Analytics esistente o creane uno nuovo.

    Se crei un nuovo account, seleziona Analytics posizione segnalata, poi accetta le impostazioni di condivisione dei dati e i termini di Google Analytics per il tuo progetto.

  5. Fai clic su Crea progetto (o Aggiungi Firebase, se utilizzi un progetto Google Cloud esistente).

Firebase esegue automaticamente il provisioning delle risorse per il tuo progetto Firebase. Quando Completata la procedura, verrà visualizzata la pagina Panoramica di Firebase progetto nella console Firebase.

Configura l'ambiente e l'interfaccia a riga di comando di Firebase

Node.js

Per scrivere le funzioni, hai bisogno di un ambiente Node.js e dell'interfaccia a riga di comando Firebase per eseguire il deployment delle funzioni nel runtime Cloud Functions. Per installare Node.js e npm, è consigliato Node Version Manager.

Dopo aver installato Node.js e npm, installa l'interfaccia a riga di comando Firebase con il tuo metodo preferito. Per installare l'interfaccia a riga di comando tramite npm, utilizza:

npm install -g firebase-tools

Viene installato il comando firebase disponibile a livello globale. Se non va a buon fine, potresti dover modificare le autorizzazioni npm. Per eseguire l'aggiornamento alla versione più recente di firebase-tools, esegui di nuovo lo stesso comando.

Python

Per scrivere le funzioni, hai bisogno di un ambiente Python e dell'interfaccia a riga di comando Firebase per eseguire il deployment delle funzioni nel runtime Cloud Functions. Ti consigliamo di utilizzare venv per isolare le dipendenze. Le versioni Python 3.10 e 3.11 sono supportati.

Una volta installato Python, installa l'interfaccia a riga di comando Firebase con il tuo metodo preferito.

Inizializza il progetto

Quando inizili l'SDK Firebase per Cloud Functions, crei un progetto vuoto contenente le dipendenze e un codice di esempio minimo. Se utilizzi Node.js, puoi scegliere tra TypeScript o JavaScript per comporre le funzioni. Ai fini di questo tutorial, dovrai anche inizializzare Cloud Firestore.

Per inizializzare il progetto:

  1. Esegui firebase login per accedere tramite il browser e autenticare il interfaccia a riga di comando Firebase.
  2. Vai alla directory del progetto Firebase.
  3. Esegui firebase init firestore. Per questo tutorial, puoi accettare i valori predefiniti quando ti viene chiesto di specificare le regole e i file di indicizzazione di Firestore. Se non hai ancora utilizzato Cloud Firestore in questo progetto, dovrai anche selezionare una modalità di avvio e una posizione per Firestore come descritto in Iniziare a utilizzare Cloud Firestore.
  4. Esegui firebase init functions. La CLI ti chiede di scegliere un codebase esistente o di inizializzarne e nominarne uno nuovo. Quando sei solo all'inizio, sia sufficiente un singolo codebase nella posizione predefinita; in seguito, man mano che la tua implementazione si espande, vuoi organizzare le funzioni nei codebase.
  5. La CLI offre le seguenti opzioni per il supporto linguistico:

    • JavaScript
    • TypeScript
    • Python

    Per questo tutorial, seleziona JavaScript o Python. Per la creazione di script in TypeScript, consulta Scrivere funzioni con TypeScript.

  6. La CLI offre un'opzione per installare le dipendenze. È sicuro rifiutare se vuoi gestire le dipendenze in un altro modo.

Una volta completati questi comandi, la struttura del progetto sarà simile a questa:

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

Per Node.js, il file package.json creato durante l'inizializzazione contiene un'importante chiave: "engines": {"node": "18"}. Questa operazione specifica la tua versione Node.js la scrittura e il deployment delle funzioni. Puoi selezionare altre versioni supportate.

Python

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

Importa i moduli richiesti e inizializza un'app

Dopo aver completato le attività di configurazione, puoi aprire la directory di origine e iniziare ad aggiungere codice come descritto nelle sezioni seguenti. Per questo esempio, il progetto deve importare Cloud Functions e i moduli SDK Admin. Aggiungi righe come la seguente al file di origine:

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

# 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()

Queste righe caricano i moduli richiesti e inizializza un'istanza dell'app admin da cui è possibile apportare Cloud Firestore modifiche. Ovunque sia disponibile il supporto dell'SDK Admin, come avviene per FCM, Authentication e Firebase Realtime Database, offre un modo efficace per integrare Firebase utilizzando Cloud Functions.

La CLI Firebase installa automaticamente l'SDK Firebase Admin e l'SDK Firebase per i moduli Cloud Functions quando inizializza il progetto. Per ulteriori informazioni sull'aggiunta di librerie di terze parti al tuo progetto, consulta Gestisci le dipendenze.

Aggiungi la funzione "add message"

Per la funzione "add message", aggiungi queste righe al file di origine:

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

@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.")

La funzione "add message" è un endpoint HTTP. Qualsiasi richiesta all'endpoint genera oggetti di richiesta e risposta passati al gestore delle richieste per la tua piattaforma (onRequest() o on_request).

Le funzioni HTTP sono sincrone (simili alle funzioni richiamabili), quindi devi inviare una risposta il più rapidamente possibile e rimandare il lavoro utilizzando Cloud Firestore. La funzione HTTP "add message" passa un valore di testo all'endpoint HTTP e lo inserisce nel database nel percorso /messages/:documentId/original.

Aggiungi "make maiuscolo" funzione

Per la funzione "make uppercase", aggiungi queste righe al file sorgente:

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

@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})

La funzione "make uppercase" viene eseguita quando viene scritto in Cloud Firestore, definendo il documento da ascoltare. Per motivi di rendimento, devi essere il più specifico possibile.

Le parentesi graffe, ad esempio {documentId}, contengono i "parametri", ovvero i caratteri jolly che espongono i dati corrispondenti nel callback. Cloud Firestore attiva il callback ogni volta che vengono aggiunti nuovi messaggi.

In Node.js, le funzioni basate su eventi come gli eventi Cloud Firestore sono asincrone. La funzione di callback deve restituire un null, un oggetto o una Promessa. Se non restituisci nulla, la funzione scade, segnalando un errore un nuovo tentativo. Vedi Sincronizzazione, Asinc e Promesse.

Emula l'esecuzione delle tue funzioni

La Firebase Local Emulator Suite consente di creare e testare app sul computer locale anziché eseguirne il deployment di un progetto Firebase. È vivamente consigliato eseguire test locali durante lo sviluppo, anche perché riduce il rischio di errori di programmazione che potrebbero comportare costi in un ambiente di produzione (ad esempio un ciclo infinito).

Per emulare le tue funzioni:

  1. Esegui firebase emulators:start e controlla l'output dell'URL di Emulator Suite UI. Per impostazione predefinita, localhost:4000, ma potrebbe essere ospitato su un'istanza sulla macchina. Inserisci l'URL nel browser per aprire lo Emulator Suite UI.

  2. Controlla l'output del comando firebase emulators:start per l'URL della funzione HTTP. Sarà simile a: http://localhost:5001/MY_PROJECT/us-central1/addMessage, fatta eccezione per:

    1. MY_PROJECT verrà sostituito con l'ID del tuo progetto.
    2. La porta potrebbe essere diversa sulla macchina locale.
  3. Aggiungi la stringa di query ?text=uppercaseme alla fine dell'URL della funzione. Dovrebbe avere un aspetto simile a questo: http://localhost:5001/MY_PROJECT/us-central1/addMessage?text=uppercaseme. Se vuoi, puoi modificare il messaggio in maiuscolo a un modello per creare un nuovo messaggio email.

  4. Crea un nuovo messaggio aprendo l'URL in una nuova scheda del browser.

  5. Visualizza gli effetti delle funzioni in Emulator Suite UI:

    1. Nella scheda Log dovresti vedere nuovi log che indicano che le funzioni HTTP sono state eseguite correttamente:

      i functions: Beginning execution of "addMessage"

      i functions: Beginning execution of "makeUppercase"

    2. Nella scheda Firestore dovresti vedere un documento contenente il messaggio originale e la versione in maiuscolo del messaggio (se inizialmente era "uppercaseme", vedrai "UPPERCASEME").

Esegui il deployment delle funzioni in un ambiente di produzione

Una volta che le funzioni funzionano come previsto nell'emulatore, puoi procedere con il deployment, il test e l'esecuzione nell'ambiente di produzione. Aspetti da tenere presenti di cui eseguire il deployment in produzione, deve far parte del piano tariffario Blaze. Consulta Prezzi di Cloud Functions.

Per completare il tutorial, esegui il deployment delle funzioni ed esegui che li rappresentano.

  1. Esegui questo comando per eseguire il deployment delle tue funzioni:

     firebase deploy --only functions
     

    Dopo aver eseguito questo comando, l'interfaccia a riga di comando Firebase restituisce l'URL per qualsiasi Funzione HTTP endpoint. Nel terminale, dovresti vedere una riga simile alla seguente:

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

    L'URL contiene il tuo ID progetto e una regione per la funzione HTTP. Anche se ora non devi preoccuparti di nulla, alcune richieste HTTP deve specificare una location ridurre al minimo la latenza di rete.

    Se si verificano errori di accesso, ad esempio "Impossibile autorizzare l'accesso a progetto" prova a controllare l'aliasing del progetto.

  2. Utilizzando l'URL visualizzato dalla CLI, aggiungi un parametro di query di testo e apri l'URL in un browser:

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

    La funzione esegue e reindirizza il browser alla Console Firebase nella posizione del database in cui è archiviata la stringa di testo. Questo evento di scrittura attiva la funzione "make uppercase", che scrive una versione in lettere uppercase della stringa.

Dopo aver eseguito il deployment e l'esecuzione delle funzioni, puoi visualizza i log nella console Google Cloud. Se devi eliminare funzioni in fase di sviluppo o produzione, utilizza l'interfaccia a riga di comando Firebase.

In produzione, ti consigliamo di ottimizzare le prestazioni delle funzioni e di controllare i costi impostando il numero minimo e massimo di istanze da eseguire. Per ulteriori informazioni su queste opzioni di runtime, consulta Controllare il comportamento di scalabilità.

Passaggi successivi

In questa documentazione, puoi scoprire di più su come gestisci le funzioni per Cloud Functions e spiegheremo come per gestire tutti i tipi di eventi supportati da Cloud Functions.

Per scoprire di più su Cloud Functions, potrebbe anche fare quanto segue: