Configura il tuo ambiente

Spesso avrai bisogno di una configurazione aggiuntiva per le tue funzioni, ad esempio chiavi API di terze parti o impostazioni regolabili. L'SDK Firebase per Cloud Functions offre una configurazione dell'ambiente integrata per semplificare l'archiviazione e il recupero di questo tipo di dati per il tuo progetto.

Puoi scegliere tra queste opzioni:

  • Configurazione parametrizzata (consigliata per la maggior parte degli scenari). In questo modo, viene fornita una configurazione dell'ambiente fortemente tipizzata con parametri convalidati al momento del deployment, il che evita errori e semplifica il debug.
  • Configurazione basata su file delle variabili di ambiente. Con questo approccio, crei manualmente un file dotenv per caricare le variabili di ambiente.

Per la maggior parte dei casi d'uso, è consigliata la configurazione parametrizzata. Questo approccio rende disponibili i valori di configurazione sia in fase di runtime sia in fase di deployment e il deployment viene bloccato a meno che tutti i parametri non abbiano un valore valido. Al contrario, la configurazione con variabili di ambiente non è disponibile al momento del deployment.

Configurazione parametrizzata

Cloud Functions for Firebase fornisce un'interfaccia per definire i parametri di configurazione in modo dichiarativo all'interno del codebase. Il valore di questi parametri è disponibile sia durante il deployment della funzione, quando imposti le opzioni di deployment e runtime, sia durante l'esecuzione. Ciò significa che l'interfaccia a riga di comando bloccherà il deployment a meno che tutti i parametri non abbiano un valore valido.

Node.js

const { onRequest } = require('firebase-functions/v2/https');
const { defineInt, defineString } = require('firebase-functions/params');

// Define some parameters
const minInstancesConfig = defineInt('HELLO_WORLD_MININSTANCES');
const welcomeMessage = defineString('WELCOME_MESSAGE');

// To use configured parameters inside the config for a function, provide them
// directly. To use them at runtime, call .value() on them.
export const helloWorld = onRequest(
  { minInstances: minInstancesConfig },
(req, res) => {
    res.send(`${welcomeMessage.value()}! I am a function.`);
  }
);

Python

from firebase_functions import https_fn
from firebase_functions.params import IntParam, StringParam

MIN_INSTANCES = IntParam("HELLO_WORLD_MIN_INSTANCES")
WELCOME_MESSAGE = StringParam("WELCOME_MESSAGE")

# To use configured parameters inside the config for a function, provide them
# directly. To use them at runtime, call .value() on them.
@https_fn.on_request(min_instances=MIN_INSTANCES)
def hello_world(req):
    return https_fn.Response(f'{WELCOME_MESSAGE.value()}! I am a function!')

Quando esegui il deployment di una funzione con variabili di configurazione parametrizzate, l'interfaccia a riga di comando di Firebase tenta innanzitutto di caricare i relativi valori dai file .env locali. Se non sono presenti in questi file e non è impostato default, l'interfaccia a riga di comando richiederà i valori durante il deployment, quindi li salverà automaticamente in un file .env denominato .env.<project_ID> nella directory functions/:

$ firebase deploy
i  functions: preparing codebase default for deployment
? Enter a string value for ENVIRONMENT: prod
i  functions: Writing new parameter values to disk: .env.projectId
…
$ firebase deploy
i  functions: Loaded environment variables from .env.projectId

A seconda del flusso di lavoro di sviluppo, potrebbe essere utile aggiungere il file .env.<project_ID> generato al controllo della versione.

Utilizzo dei parametri nell'ambito globale

Durante il deployment, il codice delle funzioni viene caricato e ispezionato prima che i parametri abbiano valori effettivi. Ciò significa che il recupero dei valori dei parametri durante l'ambito globale comporta un errore di deployment. Se vuoi utilizzare un parametro per inizializzare un valore globale, utilizza il callback di inizializzazione onInit(). Questo callback viene eseguito prima di qualsiasi funzione in produzione, ma non viene chiamato durante il deployment, quindi è un luogo sicuro per accedere al valore di un parametro.

Node.js

const { GoogleGenerativeAI } = require('@google/generative-ai');
const { defineSecret } = require('firebase-functions/params');
const { onInit } = require('firebase-functions/v2/core');

const apiKey = defineSecret('GOOGLE_API_KEY');

let genAI;
onInit(() => {
  genAI = new GoogleGenerativeAI(apiKey.value());
})

Python

from firebase_functions.core import init
from firebase_functions.params import StringParam, PROJECT_ID
import firebase_admin
import vertexai

location = StringParam("LOCATION")

x = "hello"

@init
def initialize():
  # Note: to write back to a global, you'll need to use the "global" keyword
  # to avoid creating a new local with the same name.
  global x
  x = "world"
  firebase_admin.initialize_app()
  vertexai.init(PROJECT_ID.value, location.value)

Se utilizzi parametri di tipo Secret, tieni presente che sono disponibili solo nel processo delle funzioni che hanno associato il secret. Se un secret è associato solo in alcune funzioni, controlla se secret.value() è un valore falso prima di utilizzarlo.

Configura il comportamento dell'interfaccia a riga di comando

I parametri possono essere configurati con un oggetto Options che controlla il modo in cui l'interfaccia a riga di comando richiederà i valori. L'esempio seguente imposta le opzioni per convalidare il formato di un numero di telefono, fornire un'opzione di selezione semplice e compilare automaticamente un'opzione di selezione dal progetto Firebase:

Node.js

const { defineString } = require('firebase-functions/params');

const welcomeMessage = defineString('WELCOME_MESSAGE', {default: 'Hello World',
description: 'The greeting that is returned to the caller of this function'});

const onlyPhoneNumbers = defineString('PHONE_NUMBER', {
  input: {
    text: {
      validationRegex: /\d{3}-\d{3}-\d{4}/,
      validationErrorMessage: "Please enter
a phone number in the format XXX-YYY-ZZZZ"
    },
  },
});

const selectedOption = defineString('PARITY', {input: params.select(["odd", "even"])});

const memory = defineInt("MEMORY", {
  description: "How much memory do you need?",
  input: params.select({ "micro": 256, "chonky": 2048 }),
});

const extensions = defineList("EXTENSIONS", {
  description: "Which file types should be processed?",
  input: params.multiSelect(["jpg", "tiff", "png", "webp"]),
});

const storageBucket = defineString('BUCKET', {
  description: "This will automatically
populate the selector field with the deploying Cloud Project’s
storage buckets",
  input: params.PICK_STORAGE_BUCKET,
});

Python

from firebase_functions.params import (
    StringParam,
    ListParam,
    TextInput,
    SelectInput,
    SelectOptions,
    ResourceInput,
    ResourceType,
)

MIN_INSTANCES = IntParam("HELLO_WORLD_MIN_INSTANCES")

WELCOME_MESSAGE = StringParam(
    "WELCOME_MESSAGE",
    default="Hello World",
    description="The greeting that is returned to the caller of this function",
)

ONLY_PHONE_NUMBERS = StringParam(
    "PHONE_NUMBER",
    input=TextInput(
        validation_regex="\d{3}-\d{3}-\d{4}",
        validation_error_message="Please enter a phone number in the format XXX-YYY-XXX",
    ),
)

SELECT_OPTION = StringParam(
    "PARITY",
    input=SelectInput([SelectOptions(value="odd"), SelectOptions(value="even")]),
)

STORAGE_BUCKET = StringParam(
    "BUCKET",
    input=ResourceInput(type=ResourceType.STORAGE_BUCKET),
    description="This will automatically populate the selector field with the deploying Cloud Project's storage buckets",
)

Tipi di parametri

La configurazione parametrizzata fornisce una tipizzazione forte per i valori dei parametri e supporta anche i secret di Cloud Secret Manager. I tipi supportati sono:

  • Secret
  • Stringa
  • Booleano
  • Numero intero
  • In virgola mobile
  • Elenco (Node.js)
  • Secret JSON (Node.js)

Consulta il riferimento allo spazio dei nomi params per informazioni sulle funzioni per la definizione dei parametri.

Valori parametro ed espressioni

Firebase valuta i parametri sia al momento del deployment sia durante l'esecuzione della funzione. A causa di questi ambienti doppi, è necessario prestare particolare attenzione quando si confrontano i valori parametro e quando li si utilizza per impostare le opzioni di runtime per le funzioni.

Per passare un parametro alla funzione come opzione di runtime, passalo direttamente:

Node.js

const { onRequest } = require('firebase-functions/v2/https');
const { defineInt } = require('firebase-functions/params');
const minInstancesConfig = defineInt('HELLO_WORLD_MININSTANCES');

export const helloWorld = onRequest(
  { minInstances: minInstancesConfig },
  (req, res) => {
    //…

Python

from firebase_functions import https_fn
from firebase_functions.params import IntParam

MIN_INSTANCES = IntParam("HELLO_WORLD_MIN_INSTANCES")

@https_fn.on_request(min_instances=MIN_INSTANCES)
def hello_world(req):
    ...

Inoltre, se devi eseguire un confronto con un parametro per sapere quale opzione scegliere, devi utilizzare i comparatori integrati anziché controllare il valore:

Node.js

const { onRequest } = require('firebase-functions/v2/https');
const environment = params.defineString(‘ENVIRONMENT’, {default: 'dev'});

// use built-in comparators
const minInstancesConfig = environment.equals('PRODUCTION').thenElse(10, 1);
export const helloWorld = onRequest(
  { minInstances: minInstancesConfig },
  (req, res) => {
    //…

Python

from firebase_functions import https_fn
from firebase_functions.params import IntParam, StringParam

ENVIRONMENT = StringParam("ENVIRONMENT", default="dev")
MIN_INSTANCES = ENVIRONMENT.equals("PRODUCTION").then(10, 0)

@https_fn.on_request(min_instances=MIN_INSTANCES)
def hello_world(req):
    ...

I parametri e le espressioni dei parametri utilizzati solo in fase di runtime sono accessibili con la relativa funzione value:

Node.js

const { onRequest } = require('firebase-functions/v2/https');
const { defineString } = require('firebase-functions/params');
const welcomeMessage = defineString('WELCOME_MESSAGE');

// To use configured parameters inside the config for a function, provide them
// directly. To use them at runtime, call .value() on them.
export const helloWorld = onRequest(
(req, res) => {
    res.send(`${welcomeMessage.value()}! I am a function.`);
  }
);

Python

from firebase_functions import https_fn
from firebase_functions.params import StringParam

WELCOME_MESSAGE = StringParam("WELCOME_MESSAGE")

@https_fn.on_request()
def hello_world(req):
    return https_fn.Response(f'{WELCOME_MESSAGE.value()}! I am a function!')

Parametri integrati

L'SDK Cloud Functions offre tre parametri predefiniti, disponibili nel sottopacchetto firebase-functions/params:

Node.js

  • projectID: il progetto cloud in cui è in esecuzione la funzione.
  • databaseURL: l'URL dell'istanza di Realtime Database associata alla funzione (se abilitata nel progetto Firebase).
  • storageBucket: il bucket Cloud Storage associato alla funzione (se abilitato nel progetto Firebase).

Python

  • PROJECT_ID: il progetto cloud in cui è in esecuzione la funzione.
  • DATABASE_URL: l'URL dell'istanza di Realtime Database associata alla funzione (se abilitata nel progetto Firebase).
  • STORAGE_BUCKET: il bucket Cloud Storage associato alla funzione (se abilitato nel progetto Firebase).

Questi funzionano come parametri di stringa definiti dall'utente sotto tutti gli aspetti, ad eccezione del fatto che, poiché i loro valori sono sempre noti all'interfaccia a riga di comando di Firebase, non verranno mai richiesti durante il deployment né salvati nei file .env.

Parametri secret

I parametri di tipo Secret, definiti utilizzando defineSecret(), rappresentano parametri di stringa con un valore archiviato in Cloud Secret Manager. Anziché eseguire un controllo rispetto a un file .env locale e scrivere un nuovo valore nel file se mancante, i parametri secret controllano l'esistenza in Cloud Secret Manager e richiedono in modo interattivo il valore di un nuovo secret durante il deployment.

I parametri secret devono essere associati a singole funzioni che devono avere accesso a questi:

Node.js

const { onRequest } = require('firebase-functions/v2/https');
const { defineSecret } = require('firebase-functions/params');
const discordApiKey = defineSecret('DISCORD_API_KEY');

export const postToDiscord = onRequest(
  { secrets: [discordApiKey] },
  (req, res) => {
  const apiKey = discordApiKey.value();
    //…

Python

from firebase_functions import https_fn
from firebase_functions.params import SecretParam

DISCORD_API_KEY = SecretParam('DISCORD_API_KEY')

@https_fn.on_request(secrets=[DISCORD_API_KEY])
def post_to_discord(req):
    api_key = DISCORD_API_KEY.value

Poiché i valori dei secret sono nascosti fino all'esecuzione della funzione, non puoi utilizzarli durante la configurazione della funzione.

Secret JSON strutturati

Se hai più valori di configurazione logicamente correlati (ad esempio, le impostazioni per un servizio di terze parti), puoi archiviarli insieme come oggetto JSON strutturato all'interno di un singolo secret utilizzando defineJsonSecret(). Questo approccio può aiutarti a organizzare la configurazione e a utilizzare in modo più efficiente il livello senza costi di Cloud Secret Manager archiviando un gruppo di valori di configurazione correlati in un unico secret.

Il valore archiviato in Secret Manager deve essere una stringa JSON valida. L'SDK analizzerà automaticamente la stringa JSON in un oggetto JavaScript quando accedi a .value().

Esempio:

const { onRequest } = require('firebase-functions/v2/https');
const { defineJsonSecret } = require('firebase-functions/params');

// Define a single secret to hold all configuration for some API
const someApiConfig = defineJsonSecret('SOMEAPI_CONFIG');

exports.myApi = onRequest(
  { secrets: [someApiConfig] },
  (req, res) => {
    // someApiConfig.value() automatically parses the JSON secret
    const { apiKey, webhookSecret, clientId } = someApiConfig.value();

    // Now you can use apiKey, webhookSecret, clientId
    // ...
  }
);

Per creare il secret SOMEAPI_CONFIG, devi impostare il suo valore in Secret Manager su una stringa JSON come:

{
  "apiKey": "key_...",
  "webhookSecret": "secret_...",
  "clientId": "client_..."
}

Se il valore del secret non è un JSON valido, l'accesso a someApiConfig.value() genererà un errore in fase di runtime.

Variabili di ambiente

Cloud Functions for Firebase supporta il formato file dotenv per caricare le variabili di ambiente specificate in un file .env nel runtime dell'applicazione. Una volta eseguito il deployment, le variabili di ambiente possono essere lette tramite l'interfaccia process.env (nei progetti basati su Node.js) o os.environ (nei progetti basati su Python).

Per configurare l'ambiente in questo modo, crea un file .env nel progetto, aggiungi le variabili desiderate ed esegui il deployment:

  1. Crea un file .env nella directory functions/:

    # Directory layout:
    #   my-project/
    #     firebase.json
    #     functions/
    #       .env
    #       package.json
    #       index.js
    
  2. Apri il file .env per modificarlo e aggiungi le chiavi che preferisci. Ad esempio:

    PLANET=Earth
    AUDIENCE=Humans
    
  3. Esegui il deployment delle funzioni e verifica che le variabili di ambiente siano state caricate:

    firebase deploy --only functions
    # ...
    # i functions: Loaded environment variables from .env.
    # ...
    

Una volta eseguito il deployment delle variabili di ambiente personalizzate, il codice della funzione può accedervi:

Node.js

// Responds with "Hello Earth and Humans"
exports.hello = onRequest((request, response) => {
  response.send(`Hello ${process.env.PLANET} and ${process.env.AUDIENCE}`);
});

Python

import os

@https_fn.on_request()
def hello(req):
    return https_fn.Response(
        f"Hello {os.environ.get('PLANET')} and {os.environ.get('AUDIENCE')}"
    )

Deployment di più insiemi di variabili di ambiente

Se hai bisogno di un insieme alternativo di variabili di ambiente per i tuoi progetti Firebase (ad esempio, gestione temporanea e produzione), crea un file .env.<project or alias> e scrivi lì le variabili di ambiente specifiche del progetto. Le variabili di ambiente dei file .env e .env specifici del progetto (se esistenti) verranno incluse in tutte le funzioni di cui è stato eseguito il deployment.

Ad esempio, un progetto potrebbe includere questi tre file contenenti valori leggermente diversi per lo sviluppo e la produzione:

.env .env.dev .env.prod
PLANET=Earth

AUDIENCE=Humans

AUDIENCE=Dev Humans AUDIENCE=Prod Humans

In base ai valori di questi file separati, l'insieme di variabili di ambiente di cui viene eseguito il deployment con le tue funzioni varierà a seconda del progetto di destinazione:

$ firebase use dev
$ firebase deploy --only functions
i functions: Loaded environment variables from .env, .env.dev.
# Deploys functions with following user-defined environment variables:
#   PLANET=Earth
#   AUDIENCE=Dev Humans

$ firebase use prod
$ firebase deploy --only functions
i functions: Loaded environment variables from .env, .env.prod.
# Deploys functions with following user-defined environment variables:
#   PLANET=Earth
#   AUDIENCE=Prod Humans

Variabili di ambiente riservate

Alcune chiavi delle variabili di ambiente sono riservate per uso interno. Non utilizzare nessuna di queste chiavi nei file .env:

  • Tutte le chiavi che iniziano con X_GOOGLE_
  • Tutte le chiavi che iniziano con EXT_
  • Tutte le chiavi che iniziano con FIREBASE_
  • Qualsiasi chiave del seguente elenco:
  • CLOUD_RUNTIME_CONFIG
  • ENTRY_POINT
  • GCP_PROJECT
  • GCLOUD_PROJECT
  • GOOGLE_CLOUD_PROJECT
  • FUNCTION_TRIGGER_TYPE
  • FUNCTION_NAME
  • FUNCTION_MEMORY_MB
  • FUNCTION_TIMEOUT_SEC
  • FUNCTION_IDENTITY
  • FUNCTION_REGION
  • FUNCTION_TARGET
  • FUNCTION_SIGNATURE_TYPE
  • K_SERVICE
  • K_REVISION
  • PORT
  • K_CONFIGURATION

Archivia e accedi a informazioni di configurazione sensibili

Le variabili di ambiente archiviate nei file .env possono essere utilizzate per la configurazione delle funzioni, ma non devono essere considerate un modo sicuro per archiviare informazioni sensibili come credenziali del database o chiavi API. Questo è particolarmente importante se inserisci i file .env nel controllo del codice sorgente.

Per aiutarti ad archiviare informazioni di configurazione sensibili, Cloud Functions for Firebase si integra con Google Cloud Secret Manager. Questo servizio criptato archivia i valori di configurazione in modo sicuro, consentendo al contempo un facile accesso dalle tue funzioni quando necessario.

Crea e utilizza un secret

Per creare un secret, utilizza l'interfaccia a riga di comando Firebase.

Per creare e utilizzare un secret:

  1. Dalla directory principale del progetto locale, esegui questo comando:

    firebase functions:secrets:set SECRET_NAME

  2. Inserisci un valore per SECRET_NAME.

    L'interfaccia a riga di comando restituisce un messaggio di operazione riuscita e avvisa che devi eseguire il deployment delle funzioni affinché la modifica abbia effetto.

  3. Prima del deployment, assicurati che il codice delle funzioni consenta alla funzione di accedere al secret utilizzando l'opzione secrets:

    Node.js

    const { onRequest } = require('firebase-functions/v2/https');
    
    exports.processPayment = onRequest(
      { secrets: ["SECRET_NAME"] },
      (req, res) => {
        const myBillingService = initializeBillingService(
          // reference the secret value
          process.env.SECRET_NAME
        );
        // Process the payment
      }
    );

    Python

    import os
    from firebase_functions import https_fn
    
    @https_fn.on_request(secrets=["SECRET_NAME"])
    def process_payment(req):
        myBillingService = initialize_billing(key=os.environ.get('SECRET_NAME'))
        # Process the payment
        ...
    
  4. Esegui il deployment di Cloud Functions:

    firebase deploy --only functions

    Ora potrai accedervi come a qualsiasi altra variabile di ambiente. Al contrario, se un'altra funzione che non specifica il secret tenta di accedere al secret, riceve un valore non definito:

    Node.js

    exports.anotherEndpoint = onRequest((request, response) => {
      response.send(`The secret API key is ${process.env.SECRET_NAME}`);
      // responds with "The secret API key is undefined" because the `secrets` option is missing
    });
    

    Python

    @https_fn.on_request()
    def another_endpoint(req):
        return https_fn.Response(f"The secret API key is {os.environ.get("SECRET_NAME")}")
        # Responds with "The secret API key is None" because the `secrets` parameter is missing.
    

Una volta eseguito il deployment della funzione, questa avrà accesso al valore del secret. Solo le funzioni che includono specificamente un secret nell'opzione secrets avranno accesso a quel secret come variabile di ambiente. In questo modo, i valori dei secret sono disponibili solo dove sono necessari, riducendo il rischio di fuga accidentale di un secret.

Gestione dei secret

Utilizza l'interfaccia a riga di comando Firebase per gestire i secret. Quando gestisci i secret in questo modo, tieni presente che alcune modifiche all'interfaccia a riga di comando richiedono la modifica e/o il deployment delle funzioni associate. In particolare:

  • Ogni volta che imposti un nuovo valore per un secret, devi rifare il deployment di tutte le funzioni che fanno riferimento a quel secret affinché acquisiscano il valore più recente.
  • Se elimini un secret, assicurati che nessuna delle funzioni di cui hai eseguito il deployment faccia riferimento a quel secret. Le funzioni che utilizzano un valore secret eliminato non riusciranno senza messaggi di errore.

Ecco un riepilogo dei comandi dell'interfaccia a riga di comando Firebase per la gestione dei secret:

# Change the value of an existing secret
firebase functions:secrets:set SECRET_NAME

# Set secret from file
firebase functions:secrets:set SECRET_NAME --data-file file.json

# Validate secret value as json
cat file.json | firebase functions:secrets:set SECRET_NAME --format=json

# Pipe from stdin and set secret
cat file.json | firebase functions:secrets:set SECRET_NAME --format=json

# View the value of a secret
functions:secrets:access SECRET_NAME

# Destroy a secret
functions:secrets:destroy SECRET_NAME

# View all secret versions and their state
functions:secrets:get SECRET_NAME

# Automatically clean up all secrets that aren't referenced by any of your functions
functions:secrets:prune

Per i comandi access e destroy, puoi fornire il parametro facoltativo version per gestire una versione specifica. Ad esempio:

functions:secrets:access SECRET_NAME[@VERSION]

Per saperne di più su queste operazioni, passa -h con il comando per visualizzare la guida dell'interfaccia a riga di comando.

Come vengono fatturati i secret

Secret Manager consente di avere 6 versioni di secret attive senza costi. Ciò significa che puoi avere 6 secret al mese in un progetto Firebase senza costi.

Per impostazione predefinita, l'interfaccia a riga di comando Firebase tenta di distruggere automaticamente le versioni dei secret inutilizzate, se opportuno, ad esempio quando esegui il deployment di funzioni con una nuova versione del secret. Inoltre, puoi ripulire attivamente i secret inutilizzati utilizzando functions:secrets:destroy e functions:secrets:prune.

Secret Manager consente 10.000 operazioni di accesso mensili non fatturate su un secret. Le istanze di funzione leggono solo i secret specificati nell'opzione secrets ogni volta che vengono avviate a freddo. Se hai molte istanze di funzioni che leggono molti secret, il tuo progetto potrebbe superare questa quota, nel qual caso ti verranno addebitati 0,03 $per 10.000 operazioni di accesso.

Per saperne di più, consulta i prezzi di Secret Manager.

Supporto degli emulatori

La configurazione dell'ambiente con dotenv è progettata per interagire con un emulatore Cloud Functions locale.

Quando utilizzi un emulatore Cloud Functions locale, puoi eseguire l'override delle variabili di ambiente per il tuo progetto configurando un file .env.local. I contenuti di .env.local hanno la precedenza su .env e sul file .env specifico del progetto.

Ad esempio, un progetto potrebbe includere questi tre file contenenti valori leggermente diversi per lo sviluppo e i test locali:

.env .env.dev .env.local
PLANET=Earth

AUDIENCE=Humans

AUDIENCE=Dev Humans AUDIENCE=Local Humans

Quando viene avviato nel contesto locale, l'emulatore carica le variabili di ambiente come mostrato:

  $ firebase emulators:start
  i  emulators: Starting emulators: functions
  # Starts emulator with following environment variables:
  #  PLANET=Earth
  #  AUDIENCE=Local Humans

Secret e credenziali nell'emulatore Cloud Functions

L'emulatore Cloud Functions supporta l'utilizzo di secret per archiviare e accedere a informazioni di configurazione sensibili. Per impostazione predefinita, l'emulatore tenterà di accedere ai secret di produzione utilizzando le credenziali predefinite dell'applicazione. In alcune situazioni, come gli ambienti CI, l'emulatore potrebbe non riuscire ad accedere ai valori dei secret a causa di limitazioni delle autorizzazioni.

Analogamente al supporto dell'emulatore Cloud Functions per le variabili di ambiente, puoi eseguire l'override dei valori dei secret configurando un file .secret.local. In questo modo puoi testare facilmente le funzioni localmente, soprattutto se non hai accesso al valore del secret.

Esegui la migrazione dalla configurazione di runtime

L'API functions.config è deprecata e verrà ritirata a marzo 2027. Dopo questa data, i deployment con functions.config non andranno a buon fine.

Per evitare errori di deployment, esegui la migrazione della configurazione a Cloud Secret Manager utilizzando l'interfaccia a riga di comando Firebase. Questa opzione è vivamente consigliata in quanto rappresenta il modo più efficiente e sicuro per eseguire la migrazione della configurazione.

  1. Esporta la configurazione con l'interfaccia a riga di comando Firebase

    Utilizza il comando config export per esportare la configurazione dell'ambiente esistente in un nuovo secret in Cloud Secret Manager:

    $ firebase functions:config:export
    i  This command retrieves your Runtime Config values (accessed via functions.config())
       and exports them as a Secret Manager secret.
    
    i  Fetching your existing functions.config() from your project...  ✔
       Fetched your existing functions.config().
    
    i  Configuration to be exported:
    ⚠  This may contain sensitive data. Do not share this output.
    
    {
       ...
    }
    
    ✔ What would you like to name the new secret for your configuration? RUNTIME_CONFIG
    
    ✔  Created new secret version projects/project/secrets/RUNTIME_CONFIG/versions/1```
    
  2. Aggiorna il codice della funzione per associare i secret

    Per utilizzare la configurazione archiviata nel nuovo secret in Secret Manager di Cloud, utilizza l'API defineJsonSecret nell'origine della funzione. Inoltre, assicurati che i secret siano associati a tutte le funzioni che ne hanno bisogno.

    Prima

    const functions = require("firebase-functions/v1");
    
    exports.myFunction = functions.https.onRequest((req, res) => {
      const apiKey = functions.config().someapi.key;
      // ...
    });
    

    Dopo

    const { onRequest } = require("firebase-functions/v2/https");
    const { defineJsonSecret } = require("firebase-functions/params");
    
    const config = defineJsonSecret("RUNTIME_CONFIG");
    
    exports.myFunction = onRequest(
      // Bind secret to your function
      { secrets: [config] },
      (req, res) => {
        // Access secret values via .value()
        const apiKey = config.value().someapi.key;
        // ...
    });
    
  3. Esegui il deployment delle funzioni

    Esegui il deployment delle funzioni aggiornate per applicare le modifiche e associare le autorizzazioni per i secret.

    firebase deploy --only functions:<your-function-name>
    

Variabili di ambiente compilate automaticamente

Esistono variabili di ambiente che vengono compilate automaticamente nel runtime delle funzioni e nelle funzioni emulate localmente. Queste includono quelle compilate da Google Cloud, oltre a una variabile di ambiente specifica di Firebase:

process.env.FIREBASE_CONFIG: Fornisce le seguenti informazioni di configurazione del progetto Firebase:

{
  databaseURL: 'https://DATABASE_NAME.firebaseio.com',
  storageBucket: 'PROJECT_ID.firebasestorage.app',
  projectId: 'PROJECT_ID'
}

Tieni presente che i valori nella configurazione Firebase effettiva potrebbero variare a seconda delle risorse di cui hai eseguito il provisioning nel progetto.

Questa configurazione viene applicata automaticamente quando inizializzi l'SDK Firebase Admin senza argomenti. Se scrivi funzioni in JavaScript, inizializza in questo modo:

const admin = require('firebase-admin');
admin.initializeApp();

Se scrivi funzioni in TypeScript, inizializza in questo modo:

import * as functions from 'firebase-functions/v1';
import * as admin from 'firebase-admin';
import 'firebase-functions/v1';
admin.initializeApp();

Se devi inizializzare l'SDK Admin con la configurazione predefinita del progetto utilizzando le credenziali dell'account di servizio, puoi caricare le credenziali da un file e aggiungerle a FIREBASE_CONFIG in questo modo:

serviceAccount = require('./serviceAccount.json');

const adminConfig = JSON.parse(process.env.FIREBASE_CONFIG);
adminConfig.credential = admin.credential.cert(serviceAccount);
admin.initializeApp(adminConfig);