Configura il tuo ambiente

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

Puoi scegliere tra le seguenti opzioni:

  • Configurazione con parametri (consigliata per la maggior parte degli scenari). Fornisce una configurazione di ambiente con parametri con tipi definiti che vengono convalidati al momento del deployment, il che previene gli errori e semplifica il debug.
  • Configurazione basata su file delle variabili di ambiente. Con questo approccio, crei manualmente un file .env per caricare le variabili di ambiente.

Per la maggior parte dei casi d'uso, è consigliata la configurazione con parametri. 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 le variabili di ambiente non è disponibile in fase di deployment.

Configurazione con parametri

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 si impostano 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 con parametri, 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 alcun default, l'interfaccia a riga di comando ti chiederà i valori durante il deployment e li salverà automaticamente in un .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 generato .env.<project_ID> 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. Nei casi in cui vuoi utilizzare un parametro per inizializzare un valore globale, utilizza il callback di inizializzazione onInit(). Questo callback viene eseguito prima dell'esecuzione 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 a cui è stato associato il secret. Se un secret è associato solo ad alcune funzioni, verifica se secret.value() è falso prima di utilizzarlo.

Configurare 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 ti chiederà i valori. L'esempio seguente imposta le opzioni per convalidare il formato di un numero di telefono, per fornire una semplice opzione di selezione e per 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 con parametri fornisce una definizione dei tipi 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)

Per informazioni sulle funzioni per la definizione dei parametri, consulta il riferimento allo spazio dei nomi params.

Valori ed espressioni dei parametri

Firebase valuta i parametri sia in fase di deployment sia durante l'esecuzione della funzione. A causa di questi due ambienti, è necessario prestare particolare attenzione quando si confrontano i valori dei parametri 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 confrontare 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):
    ...

È possibile accedere ai parametri e alle espressioni dei parametri utilizzati solo in fase di runtime 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 parametri funzionano come i parametri stringa definiti dall'utente in tutti gli aspetti, tranne che, poiché i loro valori sono sempre noti all'interfaccia a riga di comando di Firebase, non ti verrà mai chiesto di inserirli durante il deployment né verranno salvati nei file .env.

Parametri secret

I parametri di tipo Secret, definiti utilizzando defineSecret(), rappresentano i parametri stringa il cui valore è archiviato in Cloud Secret Manager. Anziché controllare un file .env locale e scrivere un nuovo valore nel file se non è presente, i parametri secret verificano l'esistenza in Cloud Secret Manager e ti chiedono in modo interattivo il valore di un nuovo secret durante il deployment.

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

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 singolo 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 impostarne il valore in Secret Manager su una stringa JSON come la seguente:

{
  "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 dotenv formato di file 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' process.env interfaccia (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 la modifica e aggiungi le chiavi desiderate. 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')}"
    )

Eseguire il deployment di più set di variabili di ambiente

Se hai bisogno di un set alternativo di variabili di ambiente per i tuoi progetti Firebase (ad esempio, staging e produzione), crea un file e scrivi lì le variabili di ambiente specifiche del progetto..env.<project or alias> 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

Dati i valori in questi file separati, il set di variabili di ambiente di cui è stato eseguito il deployment con le funzioni varia 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

Archiviare e accedere alle 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 le credenziali del database o le chiavi API. Ciò è particolarmente importante se esegui il check-in dei file .env nel controllo del codice sorgente.

Per aiutarti ad archiviare le 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 comunque un facile accesso dalle funzioni quando necessario.

Creare e utilizzare un secret

Per creare un secret, utilizza la Firebase CLI.

Per creare e utilizzare un secret:

  1. Dalla radice della directory del progetto locale, esegui il seguente comando:

    firebase functions:secrets:set SECRET_NAME

  2. Inserisci un valore per SECRET_NAME.

    L'interfaccia a riga di comando visualizza un messaggio di riuscita e ti avvisa che devi eseguire il deployment delle funzioni affinché la modifica diventi effettiva.

  3. Prima di eseguire il 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 accedervi, 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, puoi assicurarti che i valori dei secret siano disponibili solo dove sono necessari, riducendo il rischio di divulgare accidentalmente un secret.

Gestione dei secret

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

  • Ogni volta che imposti un nuovo valore per un secret, devi rieseguire il deployment di tutte le funzioni che fanno riferimento a quel secret affinché possano recuperare l'ultimo valore.
  • Se elimini un secret, assicurati che nessuna delle funzioni di cui è stato eseguito il deployment faccia riferimento a quel secret. Le funzioni che utilizzano un valore secret eliminato non funzioneranno senza generare errori.

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 version facoltativo per gestire una versione specifica. Ad esempio:

functions:secrets:access SECRET_NAME[@VERSION]

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

Come vengono addebitati i secret

Secret Manager consente di utilizzare 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 eliminare automaticamente le versioni di secret inutilizzate , se necessario, ad esempio quando esegui il deployment di funzioni con una nuova versione del secret. Inoltre, puoi liberare spazio dai secret inutilizzati utilizzando functions:secrets:destroy e functions:secrets:prune.

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

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

Supporto dell'emulatore

La configurazione di ambiente con dotenv è progettata per interagire con un emulatore Cloud Functionslocale.

Quando utilizzi un emulatore Cloud Functions locale, puoi sostituire le 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 di seguito:

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

Secret e credenziali nell'Cloud Functions emulator

L'Cloud Functions emulatore supporta l'utilizzo dei secret per archiviare e accedere alle 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 negli ambienti CI, l'emulatore potrebbe non riuscire ad accedere ai valori dei secret a causa di limitazioni delle autorizzazioni.

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

Eseguire la migrazione dalla configurazione di runtime

L'API functions.config è obsoleta e verrà disattivata a marzo 2027. Dopo questa data, i deployment con functions.config non riusciranno.

Per evitare errori di deployment, esegui la migrazione della configurazione a Cloud Secret Manager utilizzando la CLI Firebase. Questa è la soluzione più efficiente e sicura per eseguire la migrazione della configurazione.

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

    Utilizza il comando config export per esportare la configurazione di 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. Aggiornare il codice della funzione per associare i secret

    Per utilizzare la configurazione archiviata nel nuovo secret in Cloud Secret Manager, utilizza l'API defineJsonSecret nel codice sorgente 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. Eseguire il deployment delle funzioni

    Esegui il deployment delle funzioni aggiornate per applicare le modifiche e associare le autorizzazioni dei 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, nonché 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 Admin di Firebase senza argomenti. Se scrivi funzioni in JavaScript, inizializza come segue:

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

Se scrivi funzioni in TypeScript, inizializza come segue:

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 del service account, puoi caricare le credenziali da un file e aggiungerle a FIREBASE_CONFIG come segue:

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

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