Часто вам потребуется дополнительная настройка для ваших функций, например ключи стороннего API или настраиваемые параметры. Firebase SDK для Cloud Functions предлагает встроенную конфигурацию среды, упрощающую хранение и извлечение данных такого типа для вашего проекта.
Вы можете выбрать между этими вариантами:
- Параметризованная конфигурация (рекомендуется для большинства сценариев). Это обеспечивает строго типизированную конфигурацию среды с параметрами, которые проверяются во время развертывания, что предотвращает ошибки и упрощает отладку.
- Конфигурация переменных среды на основе файлов. При таком подходе вы вручную создаете файл dotenv для загрузки переменных среды.
В большинстве случаев использования рекомендуется параметризованная конфигурация. Этот подход делает значения конфигурации доступными как во время выполнения, так и во время развертывания, а развертывание блокируется, если все параметры не имеют допустимого значения. И наоборот, конфигурация с переменными среды недоступна во время развертывания.
Параметризованная конфигурация
Cloud Functions for Firebase предоставляют интерфейс для декларативного определения параметров конфигурации внутри вашей кодовой базы. Значение этих параметров доступно как во время развертывания функции, при настройке параметров развертывания и времени выполнения, так и во время выполнения. Это означает, что CLI заблокирует развертывание, если все параметры не имеют допустимого значения.
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.`);
}
);
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!')
При развертывании функции с параметризованными переменными конфигурации интерфейс командной строки Firebase сначала пытается загрузить их значения из локальных файлов .env. Если они отсутствуют в этих файлах и не задано default
, CLI запросит значения во время развертывания, а затем автоматически сохранит их в файле .env
с именем .env.<project_ID>
в вашем каталоге 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
В зависимости от вашего рабочего процесса разработки может оказаться полезным добавить созданный файл .env.<project_ID>
в систему контроля версий.
Использование параметров в глобальной области видимости
Во время развертывания код вашей функции загружается и проверяется до того, как ваши параметры получат фактические значения. Это означает, что получение значений параметров в глобальной области приводит к сбою развертывания. В случаях, когда вы хотите использовать параметр для инициализации глобального значения, используйте обратный вызов инициализации onInit()
. Этот обратный вызов выполняется до запуска каких-либо функций в рабочей среде, но не вызывается во время развертывания, поэтому это безопасное место для доступа к значению параметра.
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());
})
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)
Если вы используете параметры типа Secret
, учтите, что они доступны только в процессе функций, привязавших секрет. Если секрет привязан только к некоторым функциям, проверьте, является ли secret.value()
ложным, прежде чем использовать его.
Настройка поведения CLI
Параметры можно настроить с помощью объекта Options
, который управляет тем, как CLI будет запрашивать значения. В следующем примере задаются параметры для проверки формата номера телефона, предоставления простого варианта выбора и автоматического заполнения параметра выбора из проекта Firebase:
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,
});
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",
)
Типы параметров
Параметризованная конфигурация обеспечивает строгую типизацию значений параметров, а также поддерживает секреты из Cloud Secret Manager. Поддерживаемые типы:
- Секрет
- Нить
- логическое значение
- Целое число
- Плавать
- Список (Node.js)
Значения параметров и выражения
Firebase оценивает ваши параметры как во время развертывания, так и во время выполнения вашей функции. Из-за этих двойных сред необходимо проявлять особую осторожность при сравнении значений параметров и при их использовании для установки параметров времени выполнения для ваших функций.
Чтобы передать параметр в функцию в качестве параметра времени выполнения, передайте его напрямую:
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) => {
//…
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):
...
Кроме того, если вам нужно сравнить параметр, чтобы узнать, какой вариант выбрать, вам нужно будет использовать встроенные компараторы вместо проверки значения:
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) => {
//…
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):
...
Доступ к параметрам и выражениям параметров, которые используются только во время выполнения, можно получить с помощью их функции value
:
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.`);
}
);
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!')
Встроенные параметры
SDK Cloud Functions предлагает три предопределенных параметра, доступных в подпакете firebase-functions/params
:
-
projectID
— облачный проект, в котором выполняется функция. -
databaseURL
— URL-адрес экземпляра базы данных реального времени, связанного с функцией (если включено в проекте Firebase). -
storageBucket
— сегмент облачного хранилища, связанный с функцией (если он включен в проекте Firebase).
-
PROJECT_ID
— облачный проект, в котором выполняется функция. -
DATABASE_URL
— URL-адрес экземпляра базы данных реального времени, связанного с функцией (если включен в проекте Firebase). -
STORAGE_BUCKET
— сегмент облачного хранилища, связанный с функцией (если он включен в проекте Firebase).
Они функционируют как определяемые пользователем строковые параметры во всех отношениях, за исключением того, что, поскольку их значения всегда известны интерфейсу командной строки Firebase, их значения никогда не будут запрашиваться при развертывании и не сохраняться в файлах .env
.
Секретные параметры
Параметры типа Secret
, определенные с помощью defineSecret()
, представляют собой строковые параметры, значения которых хранятся в Cloud Secret Manager. Вместо проверки локального файла .env
и записи в него нового значения, если оно отсутствует, секретные параметры проверяются на наличие в Cloud Secret Manager и в интерактивном режиме запрашивают значение нового секрета во время развертывания.
Определенные таким образом секретные параметры должны быть привязаны к отдельным функциям, которые должны иметь к ним доступ:
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();
//…
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
Поскольку значения секретов скрыты до выполнения функции, вы не можете использовать их при настройке функции.
Переменные среды
Cloud Functions for Firebase поддерживают формат файла dotenv для загрузки переменных среды, указанных в файле .env
, в среду выполнения вашего приложения. После развертывания переменные среды можно прочитать через process.env
(в проектах на основе Node.js) или os.environ
(в проектах на основе Python).
Чтобы настроить среду таким образом, создайте файл .env
в своем проекте, добавьте нужные переменные и разверните:
Создайте файл
.env
в каталогеfunctions/
:# Directory layout: # my-project/ # firebase.json # functions/ # .env # package.json # index.js
Откройте файл
.env
для редактирования и добавьте нужные ключи. Например:PLANET=Earth AUDIENCE=Humans
Разверните функции и убедитесь, что переменные среды загружены:
firebase deploy --only functions # ... # i functions: Loaded environment variables from .env. # ...
После развертывания ваших пользовательских переменных среды ваш функциональный код сможет получить к ним доступ:
// Responds with "Hello Earth and Humans"
exports.hello = onRequest((request, response) => {
response.send(`Hello ${process.env.PLANET} and ${process.env.AUDIENCE}`);
});
import os
@https_fn.on_request()
def hello(req):
return https_fn.Response(
f"Hello {os.environ.get('PLANET')} and {os.environ.get('AUDIENCE')}"
)
Развертывание нескольких наборов переменных среды
Если вам нужен альтернативный набор переменных среды для ваших проектов Firebase (например, промежуточный или производственный), создайте файл .env. <project or alias >
и запишите туда переменные среды, специфичные для проекта. Переменные среды из .env
и файлов .env
, специфичных для проекта (если они существуют), будут включены во все развернутые функции.
Например, проект может включать в себя эти три файла, содержащие немного разные значения для разработки и производства:
.env | .env.dev | .env.prod |
ПЛАНЕТА=Земля АУДИТОРИЯ=Люди | АУДИТОРИЯ = Люди-разработчики | АУДИТОРИЯ=Продюсеры |
Учитывая значения в этих отдельных файлах, набор переменных среды, развернутых с вашими функциями, будет варьироваться в зависимости от вашего целевого проекта:
$ 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
Зарезервированные переменные среды
Некоторые ключи переменных среды зарезервированы для внутреннего использования. Не используйте ни один из этих ключей в ваших файлах .env
:
- Все ключи, начинающиеся с X_GOOGLE_
- Все ключи, начиная с EXT_
- Все ключи, начинающиеся с FIREBASE_
- Любой ключ из следующего списка:
- CLOUD_RUNTIME_CONFIG
- ENTRY_POINT
- GCP_PROJECT
- GCLOUD_PROJECT
- GOOGLE_CLOUD_PROJECT
- FUNCTION_TRIGGER_TYPE
- ФУНКЦИЯ_ИМЯ
- FUNCTION_MEMORY_МБ
- FUNCTION_TIMEOUT_SEC
- FUNCTION_IDENTITY
- FUNCTION_REGION
- FUNCTION_TARGET
- FUNCTION_SIGNATURE_TYPE
- К_СЕРВИС
- К_РЕВИЗИЯ
- ПОРТ
- K_КОНФИГУРАЦИЯ
Храните и получайте доступ к конфиденциальной информации о конфигурации.
Переменные среды, хранящиеся в файлах .env
можно использовать для конфигурации функций, но не следует рассматривать их как безопасный способ хранения конфиденциальной информации, такой как учетные данные базы данных или ключи API. Это особенно важно, если вы проверяете свои файлы .env
в системе контроля версий.
Чтобы помочь вам хранить конфиденциальную информацию о конфигурации, Cloud Functions for Firebase интегрируется с Google Cloud Secret Manager . Эта зашифрованная служба надежно хранит значения конфигурации, но при этом обеспечивает легкий доступ к вашим функциям, когда это необходимо.
Создайте и используйте секрет
Чтобы создать секрет, используйте интерфейс командной строки Firebase .
Чтобы создать и использовать секрет:
Из корня локального каталога проекта выполните следующую команду:
firebase functions:secrets:set
SECRET_NAME Введите значение SECRET_NAME .
Интерфейс командной строки отображает сообщение об успехе и предупреждает, что вам необходимо развернуть функции, чтобы изменения вступили в силу.
Перед развертыванием убедитесь, что код вашей функции позволяет функции получить доступ к секрету с помощью параметра
runWith
: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 } );
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 ...
Развертывание Cloud Functions :
firebase deploy --only functions
Теперь вы сможете получить к ней доступ, как к любой другой переменной среды. И наоборот, если другая функция, не указывающая секрет в
runWith
попытается получить доступ к секрету, она получит неопределенное значение: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 `runWith` parameter is missing });
@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.
После развертывания вашей функции она получит доступ к секретному значению. Только функции, которые специально включают секрет в свой параметр runWith
будут иметь доступ к этому секрету как к переменной среды. Это поможет вам убедиться, что секретные значения доступны только там, где они необходимы, что снижает риск случайной утечки секрета.
Управление секретами
Используйте интерфейс командной строки Firebase для управления своими секретами. Управляя секретами таким образом, имейте в виду, что некоторые изменения CLI требуют изменения и/или повторного развертывания связанных функций. Конкретно:
- Всякий раз, когда вы устанавливаете новое значение для секрета, вы должны повторно развернуть все функции, ссылающиеся на этот секрет, чтобы они могли получить последнее значение.
- Если вы удаляете секрет, убедитесь, что ни одна из ваших развернутых функций не ссылается на этот секрет. Функции, использующие удаленное секретное значение, завершатся автоматически.
Вот краткое описание команд Firebase CLI для управления секретами:
# Change the value of an existing secret firebase functions:secrets:setSECRET_NAME # View the value of a secret functions:secrets:accessSECRET_NAME # Destroy a secret functions:secrets:destroySECRET_NAME # View all secret versions and their state functions:secrets:getSECRET_NAME # Automatically clean up all secrets that aren't referenced by any of your functions functions:secrets:prune
Для команд access
и destroy
вы можете указать необязательный параметр версии для управления конкретной версией. Например:
functions:secrets:accessSECRET_NAME [@VERSION]
Для получения дополнительной информации об этих операциях передайте -h
с командой для просмотра справки CLI.
Как выставляются счета за секреты
Secret Manager позволяет бесплатно использовать 6 активных секретных версий . Это означает, что вы можете бесплатно иметь 6 секретов в месяц в проекте Firebase.
По умолчанию интерфейс командной строки Firebase пытается автоматически уничтожить неиспользуемые версии секрета, когда это необходимо, например, когда вы развертываете функции с новой версией секрета. Кроме того, вы можете активно очищать неиспользуемые секреты, используя functions:secrets:destroy
и functions:secrets:prune
.
Secret Manager допускает 10 000 неоплачиваемых ежемесячных операций доступа к секрету. Экземпляры функций считывают только секреты, указанные в их параметре runWith
каждый раз при холодном запуске. Если у вас много экземпляров функций, читающих много секретов, ваш проект может превысить эту норму, и в этот момент с вас будет взиматься плата в размере 0,03 доллара США за 10 000 операций доступа.
Дополнительную информацию см. в разделе «Цены на Secret Manager .
Поддержка эмулятора
Конфигурация среды с помощью dotenv предназначена для взаимодействия с локальным эмулятором Cloud Functions .
При использовании локального эмулятора Cloud Functions вы можете переопределить переменные среды для своего проекта, настроив файл .env.local
. Содержимое .env.local
имеет приоритет над .env
и файлом .env
, специфичным для проекта.
Например, проект может включать в себя эти три файла, содержащие немного разные значения для разработки и локального тестирования:
.env | .env.dev | .env.local |
ПЛАНЕТА=Земля АУДИТОРИЯ=Люди | АУДИТОРИЯ = Люди-разработчики | АУДИТОРИЯ=Местные жители |
При запуске в локальном контексте эмулятор загружает переменные среды, как показано:
$ firebase emulators:start
i emulators: Starting emulators: functions
# Starts emulator with following environment variables:
# PLANET=Earth
# AUDIENCE=Local Humans
Секреты и учетные данные в эмуляторе Cloud Functions
Эмулятор Cloud Functions поддерживает использование секретов для хранения и доступа к конфиденциальной информации о конфигурации . По умолчанию эмулятор попытается получить доступ к вашим производственным секретам, используя учетные данные приложения по умолчанию . В определенных ситуациях, например в средах CI, эмулятор может не получить доступ к секретным значениям из-за ограничений разрешений.
Подобно поддержке переменных среды эмулятором Cloud Functions , вы можете переопределить значения секретов, настроив файл .secret.local
. Это упрощает локальное тестирование ваших функций, особенно если у вас нет доступа к секретному значению.
Миграция из конфигурации среды
Если вы использовали конфигурацию среды с помощью functions.config
, вы можете перенести существующую конфигурацию как переменные среды (в формате dotenv ). Интерфейс командной строки Firebase предоставляет команду экспорта, которая выводит конфигурацию каждого псевдонима или проекта, указанного в файле .firebaserc
вашего каталога (в примере ниже, local
, dev
и prod
) в виде файлов .env
.
Для миграции экспортируйте существующие конфигурации среды с помощью команды firebase functions:config:export
:
firebase functions:config:export i Importing configs from projects: [project-0, project-1] ⚠ The following configs keys could not be exported as environment variables: ⚠ project-0 (dev): 1foo.a => 1FOO\_A (Key 1FOO\_A must start with an uppercase ASCII letter or underscore, and then consist of uppercase ASCII letters, digits, and underscores.) Enter a PREFIX to rename invalid environment variable keys: CONFIG\_ ✔ Wrote functions/.env.prod ✔ Wrote functions/.env.dev ✔ Wrote functions/.env.local ✔ Wrote functions/.env
Обратите внимание, что в некоторых случаях вам будет предложено ввести префикс для переименования ключей экспортированных переменных среды. Это связано с тем, что не все конфигурации могут быть автоматически преобразованы, поскольку они могут быть недействительными или представлять собой зарезервированный ключ переменной среды .
Мы рекомендуем вам внимательно просмотреть содержимое созданных файлов .env
перед развертыванием функций или проверкой файлов .env
в системе контроля версий. Если какие-либо значения являются конфиденциальными и не должны разглашаться, удалите их из файлов .env
и вместо этого надежно сохраните их в Secret Manager .
Вам также потребуется обновить код функций. Любые функции, использующие functions.config
теперь должны будут использовать вместо этого process.env
, как показано в разделе «Переменные среды» .
Часто вам потребуется дополнительная настройка для ваших функций, например ключи стороннего API или настраиваемые параметры. Firebase SDK для Cloud Functions предлагает встроенную конфигурацию среды, упрощающую хранение и извлечение данных такого типа для вашего проекта.
Вы можете выбрать между этими вариантами:
- Параметризованная конфигурация (рекомендуется для большинства сценариев). Это обеспечивает строго типизированную конфигурацию среды с параметрами, которые проверяются во время развертывания, что предотвращает ошибки и упрощает отладку.
- Конфигурация переменных среды на основе файлов. При таком подходе вы вручную создаете файл dotenv для загрузки переменных среды.
В большинстве случаев использования рекомендуется параметризованная конфигурация. Этот подход делает значения конфигурации доступными как во время выполнения, так и во время развертывания, а развертывание блокируется, если все параметры не имеют допустимого значения. И наоборот, конфигурация с переменными среды недоступна во время развертывания.
Параметризованная конфигурация
Cloud Functions for Firebase предоставляют интерфейс для декларативного определения параметров конфигурации внутри вашей кодовой базы. Значение этих параметров доступно как во время развертывания функции, при настройке параметров развертывания и времени выполнения, так и во время выполнения. Это означает, что CLI заблокирует развертывание, если все параметры не имеют допустимого значения.
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.`);
}
);
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!')
При развертывании функции с параметризованными переменными конфигурации интерфейс командной строки Firebase сначала пытается загрузить их значения из локальных файлов .env. Если они отсутствуют в этих файлах и не задано default
, CLI запросит значения во время развертывания, а затем автоматически сохранит их в файле .env
с именем .env.<project_ID>
в вашем каталоге 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
В зависимости от вашего рабочего процесса разработки может оказаться полезным добавить созданный файл .env.<project_ID>
в систему контроля версий.
Использование параметров в глобальной области видимости
Во время развертывания код вашей функции загружается и проверяется до того, как ваши параметры получат фактические значения. Это означает, что получение значений параметров в глобальной области приводит к сбою развертывания. В случаях, когда вы хотите использовать параметр для инициализации глобального значения, используйте обратный вызов инициализации onInit()
. Этот обратный вызов выполняется до запуска каких-либо функций в рабочей среде, но не вызывается во время развертывания, поэтому это безопасное место для доступа к значению параметра.
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());
})
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)
Если вы используете параметры типа Secret
, учтите, что они доступны только в процессе функций, привязавших секрет. Если секрет привязан только к некоторым функциям, проверьте, является ли secret.value()
ложным, прежде чем использовать его.
Настройка поведения CLI
Параметры могут быть настроены с помощью объекта Options
, который контролирует, как CLI будет запрашивать значения. В следующем примере установлены параметры для проверки формата номера телефона, для предоставления простой опции выбора и автоматического заполнения опции выбора из проекта Firebase:
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,
});
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",
)
Типы параметров
Параметризованная конфигурация обеспечивает сильное печатание для значений параметров, а также поддерживает секреты от Cloud Secret Manager. Поддерживаемые типы:
- Секрет
- Нить
- Логический
- Целое число
- Плавать
- Список (node.js)
Значения и выражения параметров
Firebase оценивает ваши параметры как во время развертывания, так и во время выполнения вашей функции. Из -за этих двойных сред, необходимо привлечь некоторую дополнительную помощь при сравнении значений параметров и при их использовании для установки параметров времени выполнения для ваших функций.
Чтобы передать параметр вашей функции в качестве опции времени выполнения, передайте его напрямую:
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) => {
//…
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):
...
Кроме того, если вам нужно сравнивать с параметром, чтобы узнать, какой вариант выбрать, вам нужно использовать встроенные компараторы вместо проверки значения:
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) => {
//…
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):
...
Параметры и выражения параметров, которые используются только во время выполнения, можно получить с помощью функции value
:
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.`);
}
);
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!')
Встроенные параметры
Облачные функции SDK предлагает три предварительно определенных параметра, доступные в подпакете firebase-functions/params
:
-
projectID
- облачный проект, в котором работает функция. -
databaseURL
- URL -адрес экземпляра базы данных в реальном времени, связанный с функцией (если включен в проект Firebase). -
storageBucket
- ведро для хранения облачного хранилища, связанное с функцией (если включено в проект Firebase).
-
PROJECT_ID
- облачный проект, в котором работает функция. -
DATABASE_URL
- URL -адрес экземпляра базы данных в реальном времени, связанный с функцией (если включен в проект Firebase). -
STORAGE_BUCKET
- ведро для хранения облачного хранилища, связанное с функцией (если включено в проект Firebase).
Эти функции, подобные пользовательским параметрам строк во всех отношениях, за исключением того, что, поскольку их значения всегда известны для CLI Firebase, их значения никогда не будут предложены для развертывания и не сохранены в файлах .env
.
Секретные параметры
Параметры Secret
типа, определяемые с использованием defineSecret()
, представляют параметры строки, которые имеют значение, хранящиеся в Cloud Secret Manager. Вместо того, чтобы проверять локальный файл .env
и записывать новое значение в файл, если отсутствует, секретные параметры проверяют существование в Cloud Secret Manager и интерактивно предпринимают значение новой секрета во время развертывания.
Секретные параметры, определенные таким образом, должны быть связаны с отдельными функциями, которые должны иметь к ним доступ:
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();
//…
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
Поскольку значения секретов скрыты до выполнения функции, вы не можете использовать их при настройке вашей функции.
Переменные среды
Cloud Functions for Firebase поддерживают формат файла dotenv для загрузки переменных среды, указанных в файле .env
в время выполнения вашего приложения. После развертывания переменные среды могут быть прочитаны через интерфейс process.env
(в проектах на основе Node.js) или os.environ
(в проектах на основе Python).
Чтобы настроить свою среду таким образом, создайте файл .env
в вашем проекте, добавьте желаемые переменные и разверните:
Создайте файл
.env
в вашихfunctions/
каталоге:# Directory layout: # my-project/ # firebase.json # functions/ # .env # package.json # index.js
Откройте файл
.env
для редактирования и добавьте желаемые ключи. Например:PLANET=Earth AUDIENCE=Humans
Развернуть функции и убедитесь, что переменные среды были загружены:
firebase deploy --only functions # ... # i functions: Loaded environment variables from .env. # ...
После того, как ваши пользовательские переменные среды будут развернуты, ваш код функции может получить к ним доступ:
// Responds with "Hello Earth and Humans"
exports.hello = onRequest((request, response) => {
response.send(`Hello ${process.env.PLANET} and ${process.env.AUDIENCE}`);
});
import os
@https_fn.on_request()
def hello(req):
return https_fn.Response(
f"Hello {os.environ.get('PLANET')} and {os.environ.get('AUDIENCE')}"
)
Развертывание нескольких наборов переменных среды
Если вам нужен альтернативный набор переменных среды для ваших проектов Firebase (например, постановка против производства), создайте .env. <project or alias >
FISE и напишите там переменные среды, специфичные для проекта. Переменные среды из файлов .env
и специфичных .env
проекта (если они существуют) будут включены во все развернутые функции.
Например, проект может включать эти три файла, содержащие несколько разные значения для разработки и производства:
.env | .env.dev | .env.prod |
Планета = Земля Аудитория = люди | Аудитория = Дев | Аудитория = продувать люди |
Учитывая значения в этих отдельных файлах, набор переменных среды, развернутые с помощью ваших функций, будет варьироваться в зависимости от вашего целевого проекта:
$ 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
Зарезервированные переменные среды
Некоторые клавиши переменной среды зарезервированы для внутреннего использования. Не используйте ни одного из этих ключей в ваших файлах .env
:
- Все ключи, начиная с x_google_
- Все клавиши, запускающие ext_
- Все ключи, начиная с Firebase_
- Любой ключ из следующего списка:
- Cloud_runtime_config
- Intry_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
- ПОРТ
- K_Configuration
Хранить и получить доступ к конфигурации
Переменные среды, хранящиеся в файлах .env
, могут использоваться для конфигурации функции, но вы не должны считать их безопасным способом хранения конфиденциальной информации, такой как учетные данные базы данных или ключи API. Это особенно важно, если вы проверяете свои файлы .env
в элементе управления источником.
Чтобы помочь вам сохранить конфиденциальную информацию о конфигурации, Cloud Functions for Firebase интегрируются с Google Cloud Secret Manager . Эта зашифрованная служба сохраняет значения конфигурации надежно, при этом все еще позволяя легко получить доступ к вашим функциям, когда это необходимо.
Создать и использовать секрет
Чтобы создать секрет, используйте CLI Firebase .
Чтобы создать и использовать секрет:
Из корня вашего локального каталога проекта запустите следующую команду:
firebase functions:secrets:set
SECRET_NAME Введите значение для SECRET_NAME .
CLI повторяет сообщение о успехе и предупреждает, что вы должны развернуть функции для вступления в силу.
Перед развертыванием убедитесь, что код ваших функций позволяет функции получить доступ к секрету, используя параметр
runWith
: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 } );
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 ...
Развернуть Cloud Functions :
firebase deploy --only functions
Теперь вы сможете получить к нему доступ, как и любая другая переменная среды. И наоборот, если другая функция, которая не указывает секрет в
runWith
пытается получить доступ к секрету, она получает неопределенное значение: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 `runWith` parameter is missing });
@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.
Как только ваша функция будет развернута, она будет иметь доступ к секретному значению. Только функции, которые специально включают секрет в их параметре runWith
будут иметь доступ к этой секрете в качестве переменной среды. Это помогает вам убедиться, что секретные значения доступны только там, где они необходимы, снижая риск случайной утечки секрета.
Управление секретами
Используйте CLI Firebase для управления своими секретами. Управляя секретами таким образом, имейте в виду, что некоторые изменения CLI требуют, чтобы вы модифицировали и/или перераспределение связанных функций. Конкретно:
- Всякий раз, когда вы устанавливаете новое значение для секрета, вы должны передать все функции, которые ссылаются на то, чтобы они могли получить последнее значение.
- Если вы удалите секрет, убедитесь, что ни одна из ваших развернутых функций не ссылается на это секрет. Функции, которые используют секретное значение, которое было удалено, потерпят неудачу.
Вот краткое изложение команд CLI Firebase для секретного управления:
# Change the value of an existing secret firebase functions:secrets:setSECRET_NAME # View the value of a secret functions:secrets:accessSECRET_NAME # Destroy a secret functions:secrets:destroySECRET_NAME # View all secret versions and their state functions:secrets:getSECRET_NAME # Automatically clean up all secrets that aren't referenced by any of your functions functions:secrets:prune
Для команд access
и destroy
вы можете предоставить дополнительную версию параметр для управления конкретной версией. Например:
functions:secrets:accessSECRET_NAME [@VERSION]
Для получения дополнительной информации об этих операциях, перенесите -h
с командой, чтобы просмотреть помощь CLI.
Как считываются секреты
Secret Manager позволяет 6 Active Secret версии бесплатно. Это означает, что вы можете иметь 6 секретов в месяц в проекте Firebase бесплатно.
По умолчанию CLI Firebase пытается автоматически уничтожить неиспользованные секретные версии, например, когда вы развертываете функции с новой версией The Secret. Кроме того, вы можете активно очищать неиспользованные секреты, используя functions:secrets:destroy
и functions:secrets:prune
.
Secret Manager позволяет в секрете 10 000 невыполненных ежемесячных операций доступа. Экземпляры функций считывают только секреты, указанные в их параметре runWith
каждый раз, когда они запускаются. Если у вас есть много экземпляров функций, читающих много секретов, ваш проект может превышать это пособие, после чего вам будет взиматься 0,03 долл. США за 10 000 операций доступа.
Для получения дополнительной информации см. Цены на Secret Manager .
Поддержка эмулятора
Конфигурация среды с DotEnv предназначена для взаимодействия с локальным эмулятором Cloud Functions .
При использовании эмулятора локальных Cloud Functions вы можете переопределить переменные среды для своего проекта, настроив файл .env.local
. Содержимое .env.local
приоритет над .env
и специфичным для проекта файл .env
.
Например, проект может включать эти три файла, содержащие несколько разные значения для разработки и локального тестирования:
.env | .env.dev | .env.local |
Планета = Земля Аудитория = люди | Аудитория = Дев | Аудитория = местные люди |
При запуске в локальном контексте эмулятор загружает переменные среды, как показано:
$ firebase emulators:start
i emulators: Starting emulators: functions
# Starts emulator with following environment variables:
# PLANET=Earth
# AUDIENCE=Local Humans
Секреты и учетные данные в эмуляторе Cloud Functions
Эмулятор Cloud Functions поддерживает использование секретов для хранения и доступа к конфиденциальной информации о конфигурации . По умолчанию эмулятор попытается получить доступ к вашим производственным секретам, используя учетные данные по умолчанию приложения . В определенных ситуациях, таких как среда CI, эмулятор может не добраться до значений секрета из -за ограничений разрешения.
Подобно поддержке эмуляторов Cloud Functions для переменных среды, вы можете переопределить значения секретов, настроив файл .secret.local
. Это позволяет вам легко проверять свои функции локально, особенно если у вас нет доступа к секретному значению.
Миграция из конфигурации среды
Если вы использовали конфигурацию среды с functions.config
. CLI Firebase предоставляет команду экспорта, которая выводит конфигурацию каждого псевдоним или проекта, указанного в файле .firebaserc
вашего каталога (в примере ниже, local
, dev
и prod
) в качестве файлов .env
.
Для миграции, экспортируйте существующие конфигурации среды, используя firebase functions:config:export
Command:
firebase functions:config:export i Importing configs from projects: [project-0, project-1] ⚠ The following configs keys could not be exported as environment variables: ⚠ project-0 (dev): 1foo.a => 1FOO\_A (Key 1FOO\_A must start with an uppercase ASCII letter or underscore, and then consist of uppercase ASCII letters, digits, and underscores.) Enter a PREFIX to rename invalid environment variable keys: CONFIG\_ ✔ Wrote functions/.env.prod ✔ Wrote functions/.env.dev ✔ Wrote functions/.env.local ✔ Wrote functions/.env
Обратите внимание, что в некоторых случаях вам будет предложено ввести префикс для переименования переменных экспортируемых средств среды. Это связано с тем, что не все конфигурации могут быть автоматически преобразованы, поскольку они могут быть недействительными или могут быть зарезервированной переменной среды .
Мы рекомендуем вам тщательно просмотреть содержимое сгенерированных файлов .env
, прежде чем развернуть свои функции или проверить файлы .env
в элемент управления источником. Если какие -либо значения являются чувствительными и не должны быть просочены, удалите их из ваших файлов .env
и вместо этого храните их в Secret Manager .
Вам также нужно обновить код функций. Любые функции, которые используют functions.config
теперь должны будут использовать process.env
, как показано в переменных среды .
Часто вам понадобится дополнительная конфигурация для ваших функций, таких как сторонние клавиши API или настроенные настройки. Firebase SDK для Cloud Functions предлагает встроенную конфигурацию среды, чтобы облегчить хранение и извлечение этого типа данных для вашего проекта.
Вы можете выбрать между этими параметрами:
- Параметризованная конфигурация (рекомендуется для большинства сценариев). Это обеспечивает сильную конфигурацию среды с параметрами, которые подтверждены во время развертывания, что предотвращает ошибки и упрощает отладку.
- Файл-конфигурация переменных среды . С этим подходом вы вручную создаете файл dotenv для загрузки переменных среды.
Для большинства вариантов использования рекомендуется параметризованная конфигурация. Этот подход предоставляет значения конфигурации доступными как во время выполнения, так и во времени развертывания, а развертывание блокируется, если только все параметры не имеют допустимого значения. И наоборот, конфигурация с переменными среды недоступна во время развертывания.
Параметризованная конфигурация
Cloud Functions for Firebase предоставляют интерфейс для определения параметров конфигурации декларационной в вашей кодовой базе. Значение этих параметров доступно как во время развертывания функций, так и при установке параметров развертывания и времени выполнения, так и во время выполнения. Это означает, что CLI будет блокировать развертывание, если все параметры не имеют допустимого значения.
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.`);
}
);
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!')
При развертывании функции с параметризованными переменными конфигурации CLI Firebase впервые пытается загрузить свои значения из локальных файлов .ENV. Если они не присутствуют в этих файлах и не установлено никаких default
, CLI будет запрашивать значения во время развертывания, а затем автоматически сохранить свои значения в файле .env
с именем .env.<project_ID>
В ваших 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
В зависимости от вашего рабочего процесса разработки, может быть полезно добавить сгенерированный .env.<project_ID>
Использование параметров в глобальном объеме
Во время развертывания код ваших функций загружается и осматривается до того, как ваши параметры имеют фактические значения. Это означает, что извлечение значений параметров во время глобального объема приводит к неудаче развертывания. Для тех случаев, когда вы хотите использовать параметр для инициализации глобального значения, используйте обратный вызов инициализации onInit()
. Этот обратный вызов выполняется до того, как какие -либо функции работают в производстве, но не будут вызваны во время развертывания, поэтому это безопасное место для доступа к значению параметра.
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());
})
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)
Если вы используете параметры типа Secret
, обратите внимание, что они доступны только в процессе функций, которые связали секрет. Если секрет связан только в некоторых функциях, проверьте, является ли secret.value()
фальсификацией перед тем, как использовать его.
Настройте поведение CLI
Параметры могут быть настроены с помощью объекта Options
, который контролирует, как CLI будет запрашивать значения. В следующем примере установлены параметры для проверки формата номера телефона, для предоставления простой опции выбора и автоматического заполнения опции выбора из проекта Firebase:
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,
});
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",
)
Типы параметров
Параметризованная конфигурация обеспечивает сильное печатание для значений параметров, а также поддерживает секреты от Cloud Secret Manager. Поддерживаемые типы:
- Секрет
- Нить
- Логический
- Целое число
- Плавать
- Список (node.js)
Значения и выражения параметров
Firebase оценивает ваши параметры как во время развертывания, так и во время выполнения вашей функции. Из -за этих двойных сред, необходимо привлечь некоторую дополнительную помощь при сравнении значений параметров и при их использовании для установки параметров времени выполнения для ваших функций.
Чтобы передать параметр вашей функции в качестве опции времени выполнения, передайте его напрямую:
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) => {
//…
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):
...
Кроме того, если вам нужно сравнивать с параметром, чтобы узнать, какой вариант выбрать, вам нужно использовать встроенные компараторы вместо проверки значения:
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) => {
//…
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):
...
Параметры и выражения параметров, которые используются только во время выполнения, можно получить с помощью функции value
:
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.`);
}
);
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!')
Встроенные параметры
Облачные функции SDK предлагает три предварительно определенных параметра, доступные в подпакете firebase-functions/params
:
-
projectID
- облачный проект, в котором работает функция. -
databaseURL
- URL -адрес экземпляра базы данных в реальном времени, связанный с функцией (если включен в проект Firebase). -
storageBucket
- ведро для хранения облачного хранилища, связанное с функцией (если включено в проект Firebase).
-
PROJECT_ID
- облачный проект, в котором работает функция. -
DATABASE_URL
- URL -адрес экземпляра базы данных в реальном времени, связанный с функцией (если включен в проект Firebase). -
STORAGE_BUCKET
- ведро для хранения облачного хранилища, связанное с функцией (если включено в проект Firebase).
Эти функции, подобные пользовательским параметрам строк во всех отношениях, за исключением того, что, поскольку их значения всегда известны для CLI Firebase, их значения никогда не будут предложены для развертывания и не сохранены в файлах .env
.
Секретные параметры
Параметры Secret
типа, определяемые с использованием defineSecret()
, представляют параметры строки, которые имеют значение, хранящиеся в Cloud Secret Manager. Вместо того, чтобы проверять локальный файл .env
и записывать новое значение в файл, если отсутствует, секретные параметры проверяют существование в Cloud Secret Manager и интерактивно предпринимают значение новой секрета во время развертывания.
Секретные параметры, определенные таким образом, должны быть связаны с отдельными функциями, которые должны иметь к ним доступ:
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();
//…
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
Поскольку значения секретов скрыты до выполнения функции, вы не можете использовать их при настройке вашей функции.
Переменные среды
Cloud Functions for Firebase поддерживают формат файла dotenv для загрузки переменных среды, указанных в файле .env
в время выполнения вашего приложения. Once deployed, the environment variables can be read via the process.env
interface (in Node.js-based projects) or os.environ
(in Python-based projects).
To configure your environment this way, create a .env
file in your project, add the desired variables, and deploy:
Create a
.env
file in yourfunctions/
directory:# Directory layout: # my-project/ # firebase.json # functions/ # .env # package.json # index.js
Open the
.env
file for edit, and add the desired keys. Например:PLANET=Earth AUDIENCE=Humans
Deploy functions and verify that environment variables were loaded:
firebase deploy --only functions # ... # i functions: Loaded environment variables from .env. # ...
Once your your custom environment variables are deployed, your function code can access them:
// Responds with "Hello Earth and Humans"
exports.hello = onRequest((request, response) => {
response.send(`Hello ${process.env.PLANET} and ${process.env.AUDIENCE}`);
});
import os
@https_fn.on_request()
def hello(req):
return https_fn.Response(
f"Hello {os.environ.get('PLANET')} and {os.environ.get('AUDIENCE')}"
)
Deploying multiple sets of environment variables
If you need an alternative set of environment variables for your Firebase projects (such as staging vs production), create a .env. <project or alias >
file and write your project-specific environment variables there. The environment variables from .env
and project-specific .env
files (if they exist) will be included in all deployed functions.
For example, a project could include these three files containing slightly different values for development and production:
.env | .env.dev | .env.prod |
PLANET=Earth AUDIENCE=Humans | AUDIENCE=Dev Humans | AUDIENCE=Prod Humans |
Given the values in those separate files, the set of environment variables deployed with your functions will vary depending on your target project:
$ 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
Reserved environment variables
Some environment variable keys are reserved for internal use. Do not use any of these keys in your .env
files:
- All keys starting with X_GOOGLE_
- All keys starting EXT_
- All keys starting with FIREBASE_
- Any key from the following list:
- 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
- ПОРТ
- K_CONFIGURATION
Store and access sensitive configuration information
Environment variables stored in .env
files can be used for function configuration, but you should not consider them a secure way to store sensitive information such as database credentials or API keys. This is especially important if you check your .env
files into source control.
To help you store sensitive configuration information, Cloud Functions for Firebase integrates with Google Cloud Secret Manager . This encrypted service stores configuration values securely, while still allowing easy access from your functions when needed.
Create and use a secret
To create a secret, use the Firebase CLI.
To create and use a secret:
From the root of your local project directory, run the following command:
firebase functions:secrets:set
SECRET_NAME Enter a value for SECRET_NAME .
The CLI echoes a success message and warns that you must deploy functions for the change to take effect.
Before deploying, make sure your functions code allows the function to access the secret using the
runWith
parameter: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 } );
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 ...
Deploy Cloud Functions :
firebase deploy --only functions
Now you'll be able to access it like any other environment variable. Conversely, if another function that does not specify the secret in
runWith
tries to access the secret, it receives an undefined value: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 `runWith` parameter is missing });
@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.
Once your function is deployed, it will have access to the secret value. Only functions that specifically include a secret in their runWith
parameter will have access to that secret as an environment variable. This helps you make sure that secret values are only available where they're needed, reducing the risk of accidentally leaking a secret.
Managing secrets
Use the Firebase CLI to manage your secrets. While managing secrets this way, keep in mind that some CLI changes require you to modify and/or redeploy associated functions. Конкретно:
- Whenever you set a new value for a secret, you must redeploy all functions that reference that secret for them to pick up the latest value.
- If you delete a secret, make sure that none of your deployed functions references that secret. Functions that use a secret value that has been deleted will fail silently.
Here's a summary of the Firebase CLI commands for secret management:
# Change the value of an existing secret firebase functions:secrets:setSECRET_NAME # View the value of a secret functions:secrets:accessSECRET_NAME # Destroy a secret functions:secrets:destroySECRET_NAME # View all secret versions and their state functions:secrets:getSECRET_NAME # Automatically clean up all secrets that aren't referenced by any of your functions functions:secrets:prune
For the access
and destroy
commands, you can provide the optional version parameter to manage a particular version. Например:
functions:secrets:accessSECRET_NAME [@VERSION]
For more information about these operations, pass -h
with the command to view CLI help.
How secrets are billed
Secret Manager allows 6 active secret versions at no cost. This means that you can have 6 secrets per month in a Firebase project at no cost.
By default, the Firebase CLI attempts to automatically destroy unused secret versions where appropriate, such as when you deploy functions with a new version of the secret. Also, you can actively clean up unused secrets using functions:secrets:destroy
and functions:secrets:prune
.
Secret Manager allows 10,000 unbilled monthly access operations on a secret. Function instances read only the secrets specified in their runWith
parameter every time they cold start. If you have a lot of function instances reading a lot of secrets, your project may exceed this allowance, at which point you'll be charged $0.03 per 10,000 access operations.
For more information, see Secret Manager Pricing .
Поддержка эмулятора
Environment configuration with dotenv is designed to interoperate with a local Cloud Functions emulator .
When using a local Cloud Functions emulator, you can override environment variables for your project by setting up a .env.local
file. Contents of .env.local
take precedence over .env
and the project-specific .env
file.
For example, a project could include these three files containing slightly different values for development and local testing:
.env | .env.dev | .env.local |
PLANET=Earth AUDIENCE=Humans | AUDIENCE=Dev Humans | AUDIENCE=Local Humans |
When started in the local context, the emulator loads the environment variables as shown:
$ firebase emulators:start
i emulators: Starting emulators: functions
# Starts emulator with following environment variables:
# PLANET=Earth
# AUDIENCE=Local Humans
Secrets and credentials in the Cloud Functions emulator
The Cloud Functions emulator supports the use of secrets to store and access sensitive configuration information . By default, the emulator will try to access your production secrets using application default credentials . In certain situations like CI environments, the emulator may fail to access secret values due to permission restrictions.
Similar to Cloud Functions emulator support for environment variables, you can override secrets values by setting up a .secret.local
file. This makes it easy for you to test your functions locally, especially if you don't have access to the secret value.
Migrating from environment configuration
If you have been using environment configuration with functions.config
, you can migrate your existing configuration as environment variables (in dotenv format). The Firebase CLI provides an export command that outputs the configuration of each alias or project listed in your directory's .firebaserc
file (in the example below, local
, dev
, and prod
) as .env
files.
To migrate, export your existing environment configurations using the firebase functions:config:export
command:
firebase functions:config:export i Importing configs from projects: [project-0, project-1] ⚠ The following configs keys could not be exported as environment variables: ⚠ project-0 (dev): 1foo.a => 1FOO\_A (Key 1FOO\_A must start with an uppercase ASCII letter or underscore, and then consist of uppercase ASCII letters, digits, and underscores.) Enter a PREFIX to rename invalid environment variable keys: CONFIG\_ ✔ Wrote functions/.env.prod ✔ Wrote functions/.env.dev ✔ Wrote functions/.env.local ✔ Wrote functions/.env
Note that, in some cases, you will be prompted to enter a prefix to rename exported environment variable keys. This is because not all configurations can be automatically transformed since they may be invalid or may be a reserved environment variable key .
We recommend that you carefully review the contents of the generated .env
files before you deploy your functions or check the .env
files into source control. If any values are sensitive and should not be leaked, remove them from your .env
files and store them securely in Secret Manager instead.
You'll also need to update your functions code. Any functions that use functions.config
will now need to use process.env
instead, as shown in Environment variables .
Often you'll need additional configuration for your functions, such as third-party API keys or tuneable settings. The Firebase SDK for Cloud Functions offers built-in environment configuration to make it easy to store and retrieve this type of data for your project.
You can choose between these options:
- Parameterized configuration (recommended for most scenarios). This provides strongly-typed environment configuration with parameters that are validated at deploy time, which prevents errors and simplifies debugging.
- File-based configuration of environment variables . With this approach, you manually create a dotenv file for loading environment variables.
For most use cases, parameterized configuration is recommended. This approach makes configuration values available both at runtime and deploy time, and deployment is blocked unless all parameters have a valid value. Conversely, configuration with environment variables is not available at deploy time.
Parameterized configuration
Cloud Functions for Firebase provides an interface for defining configuration parameters declaratively inside your codebase. The value of these parameters is available both during function deployment, when setting deployment and runtime options, and during execution. This means that the CLI will block deployment unless all parameters have a valid value.
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.`);
}
);
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!')
When deploying a function with parameterized configuration variables, the Firebase CLI first attempts to load their values from local .env files. If they are not present in those files and no default
is set, the CLI will prompt for the values during deployment, and then automatically save their values to a .env
file named .env.<project_ID>
in your functions/
directory:
$ 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
Depending on your development workflow, it may be useful to add the generated .env.<project_ID>
file to version control.
Using parameters in global scope
During deployment, your functions code is loaded and inspected before your parameters have actual values. This means that fetching parameter values during global scope results in deployment failure. For cases where you want to use a parameter to initialize a global value, use the initialization callback onInit()
. This callback runs before any functions run in production but is not be called during deploy time, so it is a safe place to access a parameter's value.
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());
})
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)
If you use parameters of the type Secret
, note that they are available only in the process of functions that have bound the secret. If a secret is bound only in some functions, check whether secret.value()
is falsy before using it.
Configure CLI behavior
Parameters can be configured with an Options
object that controls how the CLI will prompt for values. The following example sets options to validate the format of a phone number, to provide a simple selection option, and to populate a selection option automatically from the Firebase project:
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,
});
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",
)
Parameter types
Parameterized configuration provides strong typing for parameter values, and also support secrets from Cloud Secret Manager. Supported types are:
- Секрет
- Нить
- Boolean
- Целое число
- Плавать
- List (Node.js)
Parameter values and expressions
Firebase evaluates your parameters both at deploy time and while your function is executing. Due to these dual environments, some extra care must be taken when comparing parameter values, and when using them to set runtime options for your functions.
To pass a parameter to your function as a runtime option, pass it directly:
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) => {
//…
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):
...
Additionally, if you need to compare against a parameter in order to know what option to pick, you'll need to use built-in comparators instead of checking the value:
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) => {
//…
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):
...
Parameters and parameter expressions that are only used at runtime can be accessed with their value
function:
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.`);
}
);
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!')
Built-in parameters
The Cloud Functions SDK offers three pre-defined parameters, available from the firebase-functions/params
subpackage:
-
projectID
— the Cloud project in which the function is running. -
databaseURL
— the URL of the Realtime Database instance associated with the function (if enabled on the Firebase project). -
storageBucket
— the Cloud Storage bucket associated with the function (if enabled on the Firebase project).
-
PROJECT_ID
— the Cloud project in which the function is running. -
DATABASE_URL
— the URL of the Realtime Database instance associated with the function (if enabled on the Firebase project). -
STORAGE_BUCKET
— the Cloud Storage bucket associated with the function (if enabled on the Firebase project).
These function like user-defined string parameters in all respects, except that, since their values are always known to the Firebase CLI, their values will never be prompted for on deployment nor saved to .env
files.
Secret parameters
Parameters of type Secret
, defined using defineSecret()
, represent string parameters which have a value stored in Cloud Secret Manager. Instead of checking against a local .env
file and writing a new value to the file if missing, secret parameters check against existence in Cloud Secret Manager, and interactively prompt for the value of a new secret during deployment.
Secret parameters defined in this way must be bound to individual functions that should have access to them:
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();
//…
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
Because the values of secrets are hidden until execution of the function, you cannot use them while configuring your function.
Переменные среды
Cloud Functions for Firebase supports the dotenv file format for loading environment variables specified in a .env
file to your application runtime. Once deployed, the environment variables can be read via the process.env
interface (in Node.js-based projects) or os.environ
(in Python-based projects).
To configure your environment this way, create a .env
file in your project, add the desired variables, and deploy:
Create a
.env
file in yourfunctions/
directory:# Directory layout: # my-project/ # firebase.json # functions/ # .env # package.json # index.js
Open the
.env
file for edit, and add the desired keys. Например:PLANET=Earth AUDIENCE=Humans
Deploy functions and verify that environment variables were loaded:
firebase deploy --only functions # ... # i functions: Loaded environment variables from .env. # ...
Once your your custom environment variables are deployed, your function code can access them:
// Responds with "Hello Earth and Humans"
exports.hello = onRequest((request, response) => {
response.send(`Hello ${process.env.PLANET} and ${process.env.AUDIENCE}`);
});
import os
@https_fn.on_request()
def hello(req):
return https_fn.Response(
f"Hello {os.environ.get('PLANET')} and {os.environ.get('AUDIENCE')}"
)
Deploying multiple sets of environment variables
If you need an alternative set of environment variables for your Firebase projects (such as staging vs production), create a .env. <project or alias >
file and write your project-specific environment variables there. The environment variables from .env
and project-specific .env
files (if they exist) will be included in all deployed functions.
For example, a project could include these three files containing slightly different values for development and production:
.env | .env.dev | .env.prod |
PLANET=Earth AUDIENCE=Humans | AUDIENCE=Dev Humans | AUDIENCE=Prod Humans |
Given the values in those separate files, the set of environment variables deployed with your functions will vary depending on your target project:
$ 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
Reserved environment variables
Some environment variable keys are reserved for internal use. Do not use any of these keys in your .env
files:
- All keys starting with X_GOOGLE_
- All keys starting EXT_
- All keys starting with FIREBASE_
- Any key from the following list:
- 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
- ПОРТ
- K_CONFIGURATION
Store and access sensitive configuration information
Environment variables stored in .env
files can be used for function configuration, but you should not consider them a secure way to store sensitive information such as database credentials or API keys. This is especially important if you check your .env
files into source control.
To help you store sensitive configuration information, Cloud Functions for Firebase integrates with Google Cloud Secret Manager . This encrypted service stores configuration values securely, while still allowing easy access from your functions when needed.
Create and use a secret
To create a secret, use the Firebase CLI.
To create and use a secret:
From the root of your local project directory, run the following command:
firebase functions:secrets:set
SECRET_NAME Enter a value for SECRET_NAME .
The CLI echoes a success message and warns that you must deploy functions for the change to take effect.
Before deploying, make sure your functions code allows the function to access the secret using the
runWith
parameter: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 } );
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 ...
Deploy Cloud Functions :
firebase deploy --only functions
Now you'll be able to access it like any other environment variable. Conversely, if another function that does not specify the secret in
runWith
tries to access the secret, it receives an undefined value: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 `runWith` parameter is missing });
@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.
Once your function is deployed, it will have access to the secret value. Only functions that specifically include a secret in their runWith
parameter will have access to that secret as an environment variable. This helps you make sure that secret values are only available where they're needed, reducing the risk of accidentally leaking a secret.
Managing secrets
Use the Firebase CLI to manage your secrets. While managing secrets this way, keep in mind that some CLI changes require you to modify and/or redeploy associated functions. Конкретно:
- Whenever you set a new value for a secret, you must redeploy all functions that reference that secret for them to pick up the latest value.
- If you delete a secret, make sure that none of your deployed functions references that secret. Functions that use a secret value that has been deleted will fail silently.
Here's a summary of the Firebase CLI commands for secret management:
# Change the value of an existing secret firebase functions:secrets:setSECRET_NAME # View the value of a secret functions:secrets:accessSECRET_NAME # Destroy a secret functions:secrets:destroySECRET_NAME # View all secret versions and their state functions:secrets:getSECRET_NAME # Automatically clean up all secrets that aren't referenced by any of your functions functions:secrets:prune
For the access
and destroy
commands, you can provide the optional version parameter to manage a particular version. Например:
functions:secrets:accessSECRET_NAME [@VERSION]
For more information about these operations, pass -h
with the command to view CLI help.
How secrets are billed
Secret Manager allows 6 active secret versions at no cost. This means that you can have 6 secrets per month in a Firebase project at no cost.
By default, the Firebase CLI attempts to automatically destroy unused secret versions where appropriate, such as when you deploy functions with a new version of the secret. Also, you can actively clean up unused secrets using functions:secrets:destroy
and functions:secrets:prune
.
Secret Manager allows 10,000 unbilled monthly access operations on a secret. Function instances read only the secrets specified in their runWith
parameter every time they cold start. If you have a lot of function instances reading a lot of secrets, your project may exceed this allowance, at which point you'll be charged $0.03 per 10,000 access operations.
For more information, see Secret Manager Pricing .
Поддержка эмулятора
Environment configuration with dotenv is designed to interoperate with a local Cloud Functions emulator .
When using a local Cloud Functions emulator, you can override environment variables for your project by setting up a .env.local
file. Contents of .env.local
take precedence over .env
and the project-specific .env
file.
For example, a project could include these three files containing slightly different values for development and local testing:
.env | .env.dev | .env.local |
PLANET=Earth AUDIENCE=Humans | AUDIENCE=Dev Humans | AUDIENCE=Local Humans |
When started in the local context, the emulator loads the environment variables as shown:
$ firebase emulators:start
i emulators: Starting emulators: functions
# Starts emulator with following environment variables:
# PLANET=Earth
# AUDIENCE=Local Humans
Secrets and credentials in the Cloud Functions emulator
The Cloud Functions emulator supports the use of secrets to store and access sensitive configuration information . By default, the emulator will try to access your production secrets using application default credentials . In certain situations like CI environments, the emulator may fail to access secret values due to permission restrictions.
Similar to Cloud Functions emulator support for environment variables, you can override secrets values by setting up a .secret.local
file. This makes it easy for you to test your functions locally, especially if you don't have access to the secret value.
Migrating from environment configuration
If you have been using environment configuration with functions.config
, you can migrate your existing configuration as environment variables (in dotenv format). The Firebase CLI provides an export command that outputs the configuration of each alias or project listed in your directory's .firebaserc
file (in the example below, local
, dev
, and prod
) as .env
files.
To migrate, export your existing environment configurations using the firebase functions:config:export
command:
firebase functions:config:export i Importing configs from projects: [project-0, project-1] ⚠ The following configs keys could not be exported as environment variables: ⚠ project-0 (dev): 1foo.a => 1FOO\_A (Key 1FOO\_A must start with an uppercase ASCII letter or underscore, and then consist of uppercase ASCII letters, digits, and underscores.) Enter a PREFIX to rename invalid environment variable keys: CONFIG\_ ✔ Wrote functions/.env.prod ✔ Wrote functions/.env.dev ✔ Wrote functions/.env.local ✔ Wrote functions/.env
Note that, in some cases, you will be prompted to enter a prefix to rename exported environment variable keys. This is because not all configurations can be automatically transformed since they may be invalid or may be a reserved environment variable key .
We recommend that you carefully review the contents of the generated .env
files before you deploy your functions or check the .env
files into source control. If any values are sensitive and should not be leaked, remove them from your .env
files and store them securely in Secret Manager instead.
You'll also need to update your functions code. Any functions that use functions.config
will now need to use process.env
instead, as shown in Environment variables .