Gestire le funzioni


Puoi eseguire il deployment, eliminare e modificare le funzioni utilizzando i comandi Firebase CLI o impostando le opzioni di runtime nel codice sorgente delle funzioni.

Funzioni di deployment

Per eseguire il deployment delle funzioni, esegui questo comando dell'interfaccia a riga di comando Firebase:

firebase deploy --only functions

Per impostazione predefinita, l'interfaccia a riga di comando Firebase esegue il deployment di tutte le funzioni contemporaneamente all'origine. Se il progetto contiene più di cinque funzioni, ti consigliamo di utilizzare il flag --only con nomi di funzioni specifici di eseguire il deployment solo delle funzioni che hai modificato. Deployment di funzioni specifiche velocizzando così il processo di deployment ed evitando di imbattersi in quote di deployment. Ad esempio:

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

Quando esegui il deployment di un numero elevato di funzioni, potresti superare la quota standard e ricevere messaggi di errore HTTP 429 o 500. Per risolvere questo, eseguire il deployment delle funzioni in gruppi di 10 o meno.

Consulta il riferimento all'interfaccia a riga di comando Firebase per l'elenco completo dei comandi disponibili.

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

Elimina funzioni

Puoi eliminare le funzioni di cui è stato eseguito il deployment in precedenza nei seguenti modi:

  • Esplicitamente nell'interfaccia a riga di comando Firebase con functions:delete
  • esplicitamente nella console Google Cloud.
  • implicitamente rimuovendo la funzione dall'origine prima del deployment.

Tutte le operazioni di eliminazione ti richiede di confermare prima di rimuovere la funzione dall'ambiente di produzione.

L'eliminazione esplicita della funzione nell'interfaccia a riga di comando di Firebase supporta più argomenti così come le funzioni e consente di specificare una funzione eseguita 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 di funzione implicita, firebase deploy analizza l'origine e rimuove dalla produzione tutte le funzioni che sono state rimosse dal file.

Modificare il nome, la regione o l'attivatore di una funzione

Se rinomini o modifichi le regioni o l'attivatore per le funzioni che gestiscono il traffico di produzione, segui i passaggi descritti in questa sezione per evitare di perdere gli eventi durante la modifica. Prima di seguire questa procedura, assicurati che il tuo è idempotente, poiché sia la nuova versione che la versione precedente della funzione verranno eseguite durante la modifica.

Rinominare una funzione

Per rinominare una funzione, crea una nuova versione rinominata della funzione nel codice sorgente e poi esegui due comandi di deployment separati. Il primo comando esegue il deployment nuova funzione con nome e il secondo comando rimuove la funzione di cui è stato eseguito completamente gestita. Ad esempio, se hai una funzione Node.js chiamata webhook che vuoi cambiare in webhookNew, rivedi il codice come segue:

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

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

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

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

Quindi esegui questi comandi per eseguire il deployment della 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 cambiando le regioni specificate per un funzione che gestisce il traffico di produzione, puoi evitare la perdita di eventi eseguendo questi passaggi nell'ordine seguente:

  1. Rinomina la funzione e modificane la regione o le regioni come preferisci.
  2. Eseguire il deployment della funzione rinominata, che comporta l'esecuzione temporanea dello stesso codice in entrambi gli insiemi di regioni.
  3. Elimina la funzione precedente.

Ad esempio, se hai una funzione chiamato webhook, che si trova attualmente la regione predefinita delle funzioni us-central1 e vuoi eseguirne la migrazione asia-northeast1, devi prima modificare il codice sorgente per rinominare il e rivedere la regione.

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

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

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

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

Poi esegui il deployment eseguendo:

firebase deploy --only functions:webhookAsia

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

Poi elimina webhook:

firebase functions:delete webhook

Ora esiste una sola funzione, webhookAsia, che viene eseguita in asia-northeast1.

Modificare il tipo di attivatore di una funzione

Man mano che sviluppi il deployment di Cloud Functions for Firebase nel tempo, potresti il tipo di trigger di una funzione per vari motivi. Ad esempio: potresti voler passare da un tipo di 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, modifica il tipo di trigger di una funzione con questa procedura:

  1. Modifica il codice sorgente in modo da includere una nuova funzione con il tipo di trigger desiderato.
  2. Eseguire il deployment della funzione, in modo da eseguire temporaneamente sia la vecchia che la nuova funzione.
  3. Elimina in modo esplicito la funzione precedente dall'ambiente di produzione utilizzando l'interfaccia a riga di comando Firebase.

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

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

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

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

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:

# 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

Impostare le opzioni di runtime

Cloud Functions for Firebase ti consente di selezionare opzioni di runtime come la versione del runtime Node.js, 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) devono essere impostate di un oggetto di configurazione all'interno del codice della funzione. Questo RuntimeOptions è la fonte attendibile per le opzioni di runtime della funzione e opzioni di override impostate tramite qualsiasi altro metodo (ad esempio tramite la console Google Cloud o gcloud CLI).

Se il flusso di lavoro di sviluppo prevede l'impostazione manuale delle opzioni di runtime tramite console Google Cloud o gcloud CLI e non vuoi che questi valori siano con override a ogni deployment, imposta l'opzione preserveExternalChanges su true. Se questa opzione è impostata su true, Firebase unisce le opzioni di runtime impostate in con le impostazioni della versione della funzione attualmente di cui è stato eseguito il deployment con la seguente priorità:

  1. L'opzione è impostata nel codice delle funzioni: sostituisci le modifiche esterne.
  2. L'opzione è impostata su RESET_VALUE nel codice delle funzioni: sostituisci le modifiche esterne con il valore predefinito.
  3. L'opzione non è impostata nel codice delle funzioni, ma è impostata nella funzione attualmente di cui è stato eseguito il deployment: utilizza l'opzione specificata nella funzione di cui è stato eseguito il deployment.

L'utilizzo dell'opzione preserveExternalChanges: true non è consigliato nella maggior parte degli scenari, perché il codice non sarà più la fonte attendibile completa per le opzioni di runtime funzioni. Se la utilizzi, controlla la console Google Cloud o utilizza gcloud CLI per visualizzare la configurazione completa di una funzione.

Imposta la versione di Node.js

L'SDK Firebase per Cloud Functions consente di selezionare il runtime di Node.js. Puoi scegliere di eseguire tutte le funzioni di un progetto esclusivamente nell'ambiente di runtime corrispondente a una di queste versioni di Node.js supportate:

  • Node.js 20 (anteprima)
  • Node.js 18
  • Node.js 16
  • Node.js 14

Per impostare la versione di Node.js:

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

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

Se utilizzi il gestore di pacchetti Yarn o hai altri requisiti specifici per il campo engines, puoi impostare il runtime per l'SDK Firebase per Cloud Functions in firebase.json invece:

  {
    "functions": {
      "runtime": "nodejs18" // or nodejs14, nodejs16 or nodejs20
    }
  }

L'interfaccia a riga di comando utilizza il valore impostato in firebase.json rispetto a qualsiasi valore o che imposti separatamente in package.json.

Esegui l'upgrade del runtime Node.js

Per eseguire l'upgrade del runtime Node.js:

  1. Assicurati che il progetto sia nel piano tariffario Blaze.
  2. Assicurati di utilizzare Firebase CLI versione 11.18.0 o successive.
  3. Modifica il valore engines nel file package.json creato in la directory functions/ durante l'inizializzazione. Ad esempio, se esegui l'upgrade dalla versione 16 alla versione 18, la voce dovrebbe avere il seguente aspetto: "engines": {"node": "18"}
  4. Se vuoi, puoi testare le modifiche utilizzando Firebase Local Emulator Suite.
  5. Esegui nuovamente il deployment di tutte le funzioni.

Controlla il comportamento di scalabilità

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

Analogamente, puoi impostare un numero massimo per limitare il ridimensionamento delle istanze in risposta alle richieste in entrata. Utilizza questa impostazione per controllare i costi o per limitare il numero di connessioni a un servizio di supporto come per configurare un database.

Riduci il numero di avvii a freddo

Per impostare il numero minimo di istanze per una funzione nel codice sorgente, utilizza il metodo runWith. Questo metodo accetta un oggetto JSON conforme alle RuntimeOptions che definisce il valore di minInstances. Ad esempio: questa funzione imposta un minimo di 5 istanze per tenere in uso:

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

Di seguito sono riportati alcuni aspetti da considerare quando imposti un valore per minInstances:

  • Se Cloud Functions for Firebase scala la tua app oltre l'impostazione minInstances, un avvio a freddo per ogni istanza al di sopra di quella soglia.
  • Gli avvii a freddo hanno l'effetto più grave sulle app con traffico irregolare. Se la tua app presenta picchi di traffico e imposti un valore minInstances sufficientemente elevato da ridurre le avviamenti a freddo a ogni aumento del traffico, noterai una latenza notevolmente ridotta. Per le app con traffico costante, gli avvii a freddo non dovrebbero influire in modo significativo sulle prestazioni.
  • L'impostazione del numero minimo di istanze può avere senso per gli ambienti di produzione, ma di solito è da evitare negli ambienti di test. Per scalare fino a zero progetto di test ma ridurre comunque gli avvii a freddo nel 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
        });
    

Limitare il numero massimo di istanze per una funzione

Per impostare le istanze massime nel codice sorgente della funzione, utilizza 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 precedente:

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 messo in coda per 30 secondi e poi rifiutato con il codice di risposta 429 Too Many Requests se nessuna istanza è disponibile entro questa data.

Per scoprire di più sulle best practice per l'utilizzo delle impostazioni del numero massimo di istanze, consulta questi best practice per l'utilizzo di maxInstances.

Impostare il timeout e l'allocazione della memoria

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

Per impostare l'allocazione e il timeout della memoria nel codice sorgente delle funzioni, utilizza il metodo runWith introdotto nell'SDK Firebase per 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, ovvero 9 minuti. La quantità di memoria concessa a una funzione corrisponde alla CPU allocata per la funzione, come descritto 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 nella console Google Cloud:

  1. Nella console Google Google Cloud, seleziona Cloud Functions dal menu a sinistra.
  2. Seleziona una funzione facendo clic sul suo nome nell'elenco delle funzioni.
  3. Fai clic sull'icona Modifica nel menu in alto.
  4. Seleziona un'allocazione della memoria dal menu a discesa con l'etichetta Memoria allocata.
  5. Fai clic su Altro per visualizzare le opzioni avanzate e inserisci un numero di secondi nella casella di testo Timeout.
  6. Fai clic su Salva per aggiornare la funzione.