了解 2023 年 Google I/O 大会上介绍的 Firebase 亮点。了解详情

Gestisci le funzioni


Puoi distribuire, eliminare e modificare le funzioni utilizzando i comandi dell'interfaccia a riga di comando di Firebase o impostando le opzioni di runtime nel codice sorgente delle funzioni.

Funzioni di distribuzione

Per distribuire le funzioni, esegui questo comando CLI di Firebase:

firebase deploy --only functions

Per impostazione predefinita, l'interfaccia a riga di comando di Firebase distribuisce contemporaneamente tutte le funzioni all'interno della sorgente. Se il tuo progetto contiene più di 5 funzioni, ti consigliamo di utilizzare il flag --only con nomi di funzioni specifici per distribuire solo le funzioni che hai modificato. La distribuzione di funzioni specifiche in questo modo velocizza il processo di distribuzione e ti aiuta a evitare di raggiungere le quote di distribuzione. Per esempio:

firebase deploy --only functions:addMessage,functions:makeUppercase

Quando si distribuisce un numero elevato di funzioni, è possibile superare la quota standard e ricevere messaggi di errore HTTP 429 o 500. Per risolvere questo problema, distribuire le funzioni in gruppi di 10 o meno.

Consulta il riferimento alla CLI di Firebase per l'elenco completo dei comandi disponibili.

Per impostazione predefinita, l'interfaccia a riga di comando di Firebase cerca nella cartella functions/ il codice sorgente. Se preferisci, puoi organizzare le funzioni in codebase o più set di file.

Elimina funzioni

È possibile eliminare le funzioni precedentemente distribuite in questi modi:

  • esplicitamente nella CLI di Firebase con functions:delete
  • esplicitamente in Google Cloud Console .
  • implicitamente rimuovendo la funzione dall'origine prima della distribuzione.

Tutte le operazioni di eliminazione richiedono una conferma prima di rimuovere la funzione dalla produzione.

L'eliminazione esplicita della funzione nella CLI di Firebase supporta più argomenti e gruppi di funzioni e consente di specificare una funzione in esecuzione in una determinata regione. Inoltre, puoi ignorare la richiesta di conferma.

# Delete all functions that match the specified name in all regions.
firebase functions:delete myFunction
# Delete a specified function running in a specific region.
firebase functions:delete myFunction --region us-east-1
# Delete more than one function
firebase functions:delete myFunction myOtherFunction
# Delete a specified functions group.
firebase functions:delete groupA
# Bypass the confirmation prompt.
firebase functions:delete myFunction --force

Con l'eliminazione implicita della funzione, firebase deploy analizza la tua fonte e rimuove dalla produzione tutte le funzioni che sono state rimosse dal file.

Modifica il nome, la regione o il trigger di una funzione

Se stai rinominando o modificando le regioni o attivando le funzioni che gestiscono il traffico di produzione, segui i passaggi in questa sezione per evitare di perdere eventi durante la modifica. Prima di seguire questi passaggi, assicurati innanzitutto che la tua funzione sia idempotente , poiché sia ​​la nuova versione che la vecchia versione della tua funzione verranno eseguite contemporaneamente durante la modifica.

Rinominare una funzione

Per rinominare una funzione, crea una nuova versione rinominata della funzione nell'origine e quindi esegui due comandi di distribuzione separati. Il primo comando distribuisce la nuova funzione denominata e il secondo comando rimuove la versione distribuita in precedenza. Ad esempio, se hai una funzione Node.js chiamata webhook che desideri modificare in webhookNew , rivedi il codice come segue:

// before
const functions = require('firebase-functions');

exports.webhook = functions.https.onRequest((req, res) => {
    res.send("Hello");
});

// after
const functions = require('firebase-functions');

exports.webhookNew = functions.https.onRequest((req, res) => {
    res.send("Hello");
});

Quindi eseguire i seguenti comandi per distribuire la nuova funzione:

# Deploy new function called webhookNew
firebase deploy --only functions:webhookNew

# Wait until deployment is done; now both webhookNew and webhook are running

# Delete webhook
firebase functions:delete webhook

Modificare la regione o le regioni di una funzione

Se stai modificando le regioni specificate per una funzione che gestisce il traffico di produzione, puoi prevenire la perdita di eventi eseguendo questi passaggi nell'ordine:

  1. Rinominare la funzione e modificarne la regione o le regioni come desiderato.
  2. Distribuisci la funzione rinominata, che comporta l'esecuzione temporanea dello stesso codice in entrambi i gruppi di regioni.
  3. Elimina la funzione precedente.

Ad esempio, se si dispone di una funzione chiamata webhook che si trova attualmente nella regione delle funzioni predefinita di us-central1 e si desidera migrarla in asia-northeast1 , è necessario prima modificare il codice sorgente per rinominare la funzione e rivedere la regione .

// before
const functions = require('firebase-functions');

exports.webhook = functions
    .https.onRequest((req, res) => {
            res.send("Hello");
    });

// after
const functions = require('firebase-functions');

exports.webhookAsia = functions
    .region('asia-northeast1')
    .https.onRequest((req, res) => {
            res.send("Hello");
    });

Quindi distribuire eseguendo:

firebase deploy --only functions:webhookAsia

Ora sono in esecuzione due funzioni identiche: webhook è in esecuzione in us-central1 e webhookAsia è in esecuzione in asia-northeast1 .

Quindi, elimina webhook :

firebase functions:delete webhook

Ora c'è solo una funzione: webhookAsia , che è in esecuzione in asia-northeast1 .

Modificare il tipo di trigger di una funzione

Man mano che sviluppi la distribuzione di Cloud Functions for Firebase nel tempo, potresti dover modificare il tipo di trigger di una funzione per vari motivi. Ad esempio, potresti voler passare da un tipo di evento Firebase Realtime Database o Cloud Firestore a un altro tipo.

Non è possibile modificare il tipo di evento di una funzione semplicemente modificando il codice sorgente ed eseguendo firebase deploy . Per evitare errori, modificare il tipo di trigger di una funzione con questa procedura:

  1. Modificare il codice sorgente per includere una nuova funzione con il tipo di trigger desiderato.
  2. Distribuire la funzione, che comporta l'esecuzione temporanea sia della vecchia che della nuova funzione.
  3. Elimina in modo esplicito la vecchia funzione dalla produzione utilizzando l'interfaccia a riga di comando di Firebase.

Ad esempio, se disponi di una funzione Node.js denominata objectChanged che ha il tipo di evento onChange legacy e desideri cambiarlo in onFinalize , rinomina prima la funzione e modificala in modo che abbia il tipo di evento onFinalize .

// before
const functions = require('firebase-functions');

exports.objectChanged = functions.storage.object().onChange((object) => {
    return console.log('File name is: ', object.name);
});

// after
const functions = require('firebase-functions');

exports.objectFinalized = functions.storage.object().onFinalize((object) => {
    return console.log('File name is: ', object.name);
});

Quindi esegui i seguenti comandi per creare prima la nuova funzione, prima di eliminare la vecchia funzione:

# Create new function objectFinalized
firebase deploy --only functions:objectFinalized

# Wait until deployment is done; now both objectChanged and objectFinalized are running

# Delete objectChanged
firebase functions:delete objectChanged

Imposta le opzioni di esecuzione

Cloud Functions for Firebase ti consente di selezionare opzioni di runtime come la versione di runtime di Node.js e il timeout per funzione, l'allocazione della memoria e le istanze di funzione minime/massime.

Come best practice, queste opzioni (ad eccezione della versione Node.js) dovrebbero essere impostate su un oggetto di configurazione all'interno del codice della funzione. Questo oggetto RuntimeOptions è la fonte della verità per le opzioni di runtime della tua funzione e sostituirà le opzioni impostate tramite qualsiasi altro metodo (ad esempio tramite la console di Google Cloud o l'interfaccia a riga di comando di gcloud).

Se il tuo flusso di lavoro di sviluppo prevede l'impostazione manuale delle opzioni di runtime tramite la console di Google Cloud o l'interfaccia a riga di comando di gcloud e non vuoi che questi valori vengano sovrascritti a ogni implementazione, imposta l'opzione preserveExternalChanges su true . Con questa opzione impostata su true , Firebase unisce le opzioni di runtime impostate nel tuo codice con le impostazioni della versione attualmente distribuita della tua funzione con la seguente priorità:

  1. L'opzione è impostata nel codice delle funzioni: ignora le modifiche esterne.
  2. L'opzione è impostata su RESET_VALUE nel codice delle funzioni: ignora le modifiche esterne con il valore predefinito.
  3. L'opzione non è impostata nel codice delle funzioni, ma è impostata nella funzione attualmente distribuita: utilizzare l'opzione specificata nella funzione distribuita.

L'uso dell'opzione preserveExternalChanges: true non è consigliato per la maggior parte degli scenari perché il tuo codice non sarà più la fonte completa della verità per le opzioni di runtime per le tue funzioni. Se lo usi, controlla la console di Google Cloud o utilizza l'interfaccia a riga di comando di gcloud per visualizzare la configurazione completa di una funzione.

Imposta la versione di Node.js

Firebase SDK for Cloud Functions 2.0.0 e versioni successive consente una selezione del runtime Node.js. Puoi scegliere di eseguire tutte le funzioni in un progetto esclusivamente nell'ambiente di runtime corrispondente a una di queste versioni di Node.js supportate:

  • Node.js 18
  • Node.js 16
  • Node.js 14

Per impostare la versione di Node.js:

Impostare la versione nel campo engines nel file package.json creato nella directory functions/ durante l'inizializzazione. Ad esempio, per utilizzare solo la versione 18, modifica questa riga in package.json :

  "engines": {"node": "18"}

Il campo engines è obbligatorio; deve specificare una delle versioni di Node.js supportate per poter distribuire ed eseguire le funzioni.

Aggiorna il tuo runtime Node.js

Per aggiornare il runtime di Node.js:

  1. Assicurati che il tuo progetto rientri nel piano tariffario di Blaze .
  2. Assicurati di utilizzare l'interfaccia a riga di comando di Firebase v11.18.0 o successiva.
  3. Modificare il valore engines nel file package.json creato nella directory functions/ durante l'inizializzazione. Ad esempio, se stai aggiornando dalla versione 16 alla versione 18, la voce dovrebbe essere simile a questa: "engines": {"node": "18"}
  4. Facoltativamente, prova le modifiche utilizzando Firebase Local Emulator Suite .
  5. Ridistribuisci tutte le funzioni.

Controlla il comportamento di ridimensionamento

Per impostazione predefinita, Cloud Functions for Firebase ridimensiona il numero di istanze in esecuzione in base al numero di richieste in entrata, riducendo potenzialmente le istanze a zero nei periodi di traffico ridotto. Tuttavia, se la tua app richiede una latenza ridotta e desideri limitare il numero di avvii a freddo, puoi modificare questo comportamento predefinito specificando un numero minimo di istanze di container da tenere al caldo e pronte a soddisfare le richieste.

Allo stesso modo, puoi impostare un numero massimo per limitare il ridimensionamento delle istanze in risposta alle richieste in arrivo. Utilizzare questa impostazione per controllare i costi o limitare il numero di connessioni a un servizio di supporto, ad esempio a un database.

Ridurre il numero di avviamenti a freddo

Per impostare il numero minimo di istanze per una funzione nel codice sorgente, utilizzare il metodo runWith . Questo metodo accetta un oggetto JSON conforme all'interfaccia RuntimeOptions , che definisce il valore per minInstances . Ad esempio, questa funzione imposta un minimo di 5 istanze per tenere al caldo:

exports.getAutocompleteResponse = functions
    .runWith({
      // Keep 5 instances warm for this latency-critical function
      minInstances: 5,
    })
    .https.onCall((data, context) => {
      // Autocomplete a user's search term
    });

Ecco alcune cose da considerare quando si imposta un valore per minInstances :

  • Se Cloud Functions for Firebase ridimensiona la tua app al di sopra dell'impostazione minInstances , si verificherà un avvio a freddo per ogni istanza al di sopra di tale soglia.
  • Gli avviamenti a freddo hanno l'effetto più grave sulle app con traffico intenso. Se la tua app ha un traffico intenso e imposti un valore minInstances sufficientemente alto da ridurre gli avviamenti a freddo a ogni aumento del traffico, noterai una latenza significativamente ridotta. Per le app con traffico costante, è improbabile che gli avviamenti a freddo influiscano gravemente sulle prestazioni.
  • L'impostazione di istanze minime può avere senso per gli ambienti di produzione, ma in genere dovrebbe essere evitata negli ambienti di test. Per scalare a zero nel tuo progetto di test ma ridurre comunque gli avviamenti a freddo nel tuo progetto di produzione, puoi impostare minInstances in base alla variabile di ambiente FIREBASE_CONFIG :

    // Get Firebase project id from `FIREBASE_CONFIG` environment variable
    const envProjectId = JSON.parse(process.env.FIREBASE_CONFIG).projectId;
    
    exports.renderProfilePage = functions
        .runWith({
          // Keep 5 instances warm for this latency-critical function
          // in production only. Default to 0 for test projects.
          minInstances: envProjectId === "my-production-project" ? 5 : 0,
        })
        .https.onRequest((req, res) => {
          // render some html
        });
    

Limita il numero massimo di istanze per una funzione

Per impostare il numero massimo di istanze nel codice sorgente della funzione, utilizzare il metodo runWith . Questo metodo accetta un oggetto JSON conforme all'interfaccia RuntimeOptions , che definisce i valori per maxInstances . Ad esempio, questa funzione imposta un limite di 100 istanze per non sovraccaricare un ipotetico database legacy:

exports.mirrorOrdersToLegacyDatabase = functions
    .runWith({
      // Legacy database only supports 100 simultaneous connections
      maxInstances: 100,
    })
    .firestore.document("orders/{orderId}")
    .onWrite((change, context) => {
      // Connect to legacy database
    });

Se una funzione HTTP viene scalata fino al limite maxInstances , le nuove richieste vengono accodate per 30 secondi e quindi rifiutate con un codice di risposta 429 Too Many Requests se nessuna istanza è disponibile per allora.

Per ulteriori informazioni sulle best practice per l'utilizzo delle impostazioni relative al numero massimo di istanze, consulta queste best practice per l'utilizzo maxInstances .

Impostare il timeout e l'allocazione della memoria

In alcuni casi, le tue funzioni potrebbero avere requisiti speciali per un lungo valore di timeout o una grande allocazione di memoria. Puoi impostare questi valori in Google Cloud Console o nel codice sorgente della funzione (solo Firebase).

Per impostare l'allocazione della memoria e il timeout nel codice sorgente delle funzioni, utilizza il parametro runWith introdotto in Firebase SDK for Cloud Functions 2.0.0. Questa opzione di runtime accetta un oggetto JSON conforme all'interfaccia RuntimeOptions , che definisce i valori per timeoutSeconds e memory . Ad esempio, questa funzione di archiviazione utilizza 1 GB di memoria e scade dopo 300 secondi:

exports.convertLargeFile = functions
    .runWith({
      // Ensure the function has enough memory and time
      // to process large files
      timeoutSeconds: 300,
      memory: "1GB",
    })
    .storage.object()
    .onFinalize((object) => {
      // Do some complicated things that take a lot of memory and time
    });

Il valore massimo per timeoutSeconds è 540 o 9 minuti. La quantità di memoria concessa a una funzione corrisponde alla CPU allocata per la funzione, come dettagliato in questo elenco di valori validi per memory :

  • 128MB — 200 MHz
  • 256MB — 400 MHz
  • 512MB — 800 MHz
  • 1GB — 1,4 GHz
  • 2GB — 2,4 GHz
  • 4GB — 4,8 GHz
  • 8GB — 4,8 GHz

Per impostare l'allocazione della memoria e il timeout in Google Cloud Console:

  1. In Google Google Cloud Console seleziona Funzioni cloud dal menu a sinistra.
  2. Selezionare una funzione facendo clic sul suo nome nell'elenco delle funzioni.
  3. Fare clic sull'icona Modifica nel menu in alto.
  4. Selezionare un'allocazione di memoria dal menu a discesa etichettato Memoria allocata .
  5. Fare clic su Altro per visualizzare le opzioni avanzate e immettere un numero di secondi nella casella di testo Timeout .
  6. Fare clic su Salva per aggiornare la funzione.