Catch up on everything announced at Firebase Summit, and learn how Firebase can help you accelerate app development and run your app with confidence. Learn More

Настройте свою среду

Оптимизируйте свои подборки Сохраняйте и классифицируйте контент в соответствии со своими настройками.

Часто вам потребуется дополнительная конфигурация для ваших функций, например сторонние ключи API или настраиваемые параметры. Firebase SDK для облачных функций предлагает встроенную конфигурацию среды, упрощающую хранение и извлечение данных этого типа для вашего проекта.

Вы можете выбрать один из трех вариантов:

  • Параметризованная конфигурация (рекомендуется для большинства сценариев). Это обеспечивает строго типизированную конфигурацию среды с параметрами, которые проверяются во время развертывания, что предотвращает ошибки и упрощает отладку.
  • Файловая конфигурация переменных окружения . При таком подходе вы вручную создаете файл dotenv для загрузки переменных среды.
  • Конфигурация среды выполнения с помощью интерфейса командной строки Firebase и functions.config .

Для большинства случаев использования рекомендуется параметризованная конфигурация. Этот подход делает значения конфигурации доступными как во время выполнения, так и во время развертывания, и развертывание блокируется, если все параметры не имеют допустимых значений. И наоборот, конфигурация с переменными среды недоступна во время развертывания.

Параметризованная конфигурация

Облачные функции для Firebase предоставляют интерфейс для декларативного определения параметров конфигурации внутри вашей кодовой базы. Значение этих параметров доступно как во время развертывания функции, при настройке параметров развертывания и выполнения, так и во время выполнения. Это означает, что интерфейс командной строки заблокирует развертывание, если все параметры не имеют допустимых значений.

Чтобы определить параметры в коде, следуйте этой модели:

const functions = require('firebase-functions');
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 = functions.runWith({ minInstances: minInstancesConfig}).https.onRequest(
  (req, res) => {
    res.send(`${welcomeMessage.value()}! I am a function.`);
  }
);

При развертывании функции с параметризованными переменными конфигурации интерфейс командной строки Firebase сначала пытается загрузить их значения из локальных файлов .env. Если они отсутствуют в этих файлах и default не установлены, интерфейс командной строки запросит значения во время развертывания, а затем автоматически сохранит их значения в файле .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> в систему управления версиями.

Настройка поведения 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: {select: {options:
[{value: "odd"}, {value: "even"}]}}})

const storageBucket = defineString('BUCKET', {input: {resource: {type:
"storage.googleapis.com/Bucket"}}, description: "This will automatically
populate the selector field with the deploying Cloud Project’s
storage buckets"})

Типы параметров

Параметризованная конфигурация обеспечивает строгую типизацию значений параметров, а также поддерживает секреты из Cloud Secret Manager. Поддерживаемые типы:

  • Секрет
  • Нить
  • логический
  • Целое число
  • Плавать

Значения параметров и выражения

Firebase оценивает ваши параметры как во время развертывания, так и во время выполнения вашей функции. Из-за этих двойных сред необходимо проявлять особую осторожность при сравнении значений параметров и при их использовании для установки параметров времени выполнения для ваших функций.

Чтобы передать параметр вашей функции в качестве параметра времени выполнения, передайте его напрямую:

const functions = require('firebase-functions');
const { defineInt} = require('firebase-functions/params');
const minInstancesConfig = defineInt('HELLO\_WORLD\_MININSTANCES');

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

Кроме того, если вам нужно сравнить с параметром, чтобы узнать, какой вариант выбрать, вам нужно будет использовать встроенные компараторы вместо проверки значения:

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

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

Доступ к параметрам и выражениям параметров, которые используются только во время выполнения, можно получить с помощью их функции value :

const functions = require('firebase-functions');
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 = functions.https.onRequest(
 (req, res) => {
    res.send(`${welcomeMessage.value()}! I am a function.`);
  }
);

Встроенные параметры

SDK облачных функций предлагает три предопределенных параметра, доступных в подпакете firebase firebase-functions/params :

  • projectId — облачный проект, в котором запущена функция.
  • databaseUrl — URL-адрес экземпляра базы данных реального времени, связанного с функцией (если она включена в проекте Firebase).
  • storageBucket — сегмент облачного хранилища, связанный с функцией (если он включен в проекте Firebase).

Эти функции аналогичны определяемым пользователем строковым параметрам во всех отношениях, за исключением того, что, поскольку их значения всегда известны интерфейсу командной строки Firebase, их значения никогда не запрашиваются при развертывании и не сохраняются в файлах .env .

Секретные параметры

Параметры типа Secret , определенные с помощью defineSecret() , представляют строковые параметры, значения которых хранятся в Cloud Secret Manager. Вместо проверки локального файла .env и записи нового значения в файл, если оно отсутствует, параметры секрета проверяют наличие в Cloud Secret Manager и интерактивно запрашивают значение нового секрета во время развертывания.

Секретные параметры, определенные таким образом, должны быть привязаны к отдельным функциям, которые должны иметь к ним доступ:

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

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

Поскольку значения секретов скрыты до выполнения функции, вы не можете использовать их при настройке своей функции.

Переменные среды

Облачные функции для Firebase поддерживают формат файла dotenv для загрузки переменных среды, указанных в файле .env , в среду выполнения вашего приложения. После развертывания переменные среды можно прочитать через интерфейс process.env .

Чтобы настроить среду таким образом, создайте файл .env в своем проекте, добавьте нужные переменные и разверните:

  1. Создайте файл .env в вашем каталоге functions/ :

    # Directory layout:
    #   my-project/
    #     firebase.json
    #     functions/
    #       .env
    #       package.json
    #       index.js
    
  2. Откройте файл .env для редактирования и добавьте нужные ключи. Например:

    PLANET=Earth
    AUDIENCE=Humans
    
  3. Разверните функции и убедитесь, что переменные среды были загружены:

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

Как только ваши пользовательские переменные среды развернуты, ваш код функции может получить к ним доступ с помощью синтаксиса process.env :

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

Развертывание нескольких наборов переменных среды

Если вам нужен альтернативный набор переменных среды для ваших проектов Firebase (например, промежуточный или производственный), создайте .env. <project or alias > и запишите туда переменные окружения, специфичные для вашего проекта. Переменные среды из .env и файлов .env для конкретного проекта (если они существуют) будут включены во все развернутые функции.

Например, проект может включать эти три файла, содержащие немного разные значения для разработки и производства:

.env .env.dev .env.prod
ПЛАНЕТА=Земля

АУДИТОРИЯ=Люди

АУДИТОРИЯ = люди-разработчики АУДИТОРИЯ=Prod Humans

Учитывая значения в этих отдельных файлах, набор переменных среды, развернутых с вашими функциями, будет различаться в зависимости от вашего целевого проекта:

$ 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
  • ТОЧКА ВХОДА
  • GCP_PROJECT
  • GCLOUD_PROJECT
  • GOOGLE_CLOUD_PROJECT
  • FUNCTION_TRIGGER_TYPE
  • ФУНКЦИЯ_ИМЯ
  • FUNCTION_MEMORY_MB
  • FUNCTION_TIMEOUT_SEC
  • FUNCTION_IDENTITY
  • FUNCTION_REGION
  • FUNCTION_TARGET
  • ФУНКЦИЯ_SIGNATURE_TYPE
  • K_SERVICE
  • K_REVISION
  • ПОРТ
  • K_КОНФИГУРАЦИЯ

Храните и получайте доступ к конфиденциальной информации о конфигурации

Переменные среды, хранящиеся в файлах .env , можно использовать для настройки функций, но вы не должны рассматривать их как безопасный способ хранения конфиденциальной информации, такой как учетные данные базы данных или ключи API. Это особенно важно, если вы проверяете файлы .env в системе контроля версий.

Чтобы помочь вам хранить конфиденциальную информацию о конфигурации, облачные функции для Firebase интегрируются с Google Cloud Secret Manager . Этот зашифрованный сервис надежно хранит значения конфигурации, но при этом обеспечивает легкий доступ из ваших функций, когда это необходимо.

Создание и использование секрета

Чтобы создать секрет, используйте интерфейс командной строки Firebase.

Чтобы создать и использовать секрет:

  1. В корневом каталоге вашего локального проекта выполните следующую команду:

    firebase functions:secrets:set SECRET_NAME

  2. Введите значение для SECRET_NAME .

    Интерфейс командной строки повторяет сообщение об успешном завершении и предупреждает, что вы должны развернуть функции, чтобы изменение вступило в силу.

  3. Перед развертыванием убедитесь, что код вашей функции позволяет функции получить доступ к секрету с помощью параметра runWith :

    exports.processPayment = functions
      // Make the secret available to this function
      .runWith({ secrets: ["SECRET_NAME"] })
      .onCall((data, context) => {
        const myBillingService = initializeBillingService(
          // reference the secret value
          process.env.SECRET_NAME
        );
        // Process the payment
      });
  4. Разверните облачные функции:

    firebase deploy --only functions

Теперь вы сможете получить к ней доступ, как и к любой другой переменной среды. И наоборот, если другая функция, которая не указывает секрет в runWith пытается получить доступ к секрету, она получает неопределенное значение:

exports.anotherEndpoint = functions.https.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
});

Как только ваша функция будет развернута, она получит доступ к секретному значению. Только функции, которые специально включают секрет в свой параметр runWith , будут иметь доступ к этому секрету как к переменной среды. Это поможет вам убедиться, что секретные значения доступны только там, где они необходимы, что снижает риск случайной утечки секрета.

Управление секретами

Используйте интерфейс командной строки Firebase для управления своими секретами. При таком управлении секретами имейте в виду, что некоторые изменения интерфейса командной строки требуют от вас изменения и/или повторного развертывания связанных функций. Конкретно:

  • Всякий раз, когда вы устанавливаете новое значение для секрета, вы должны повторно развертывать все функции, которые ссылаются на этот секрет, чтобы они получили последнее значение.
  • Если вы удаляете секрет, убедитесь, что ни одна из ваших развернутых функций не ссылается на этот секрет. Функции, использующие секретное значение, которое было удалено, завершатся автоматически.

Вот краткое описание команд Firebase CLI для управления секретами:

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

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

# Destroy a secret
functions:secrets:destroy SECRET_NAME

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

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

Для команд access и destroy вы можете указать необязательный параметр версии для управления конкретной версией. Например:

functions:secrets:access SECRET_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 , как показано в Переменные среды .

Конфигурация среды

До того, как поддержка переменных среды была выпущена в firebase-functions v3.18.0 , использование functions.config() было рекомендуемым подходом для настройки среды. Этот подход по-прежнему поддерживается, но мы рекомендуем всем новым проектам вместо этого использовать переменные среды, поскольку они проще в использовании и улучшают переносимость вашего кода.

Задайте конфигурацию среды с помощью CLI

Для хранения данных среды вы можете использовать команду firebase functions:config:set в интерфейсе командной строки Firebase . Каждому ключу можно задать пространство имен с помощью точек, чтобы сгруппировать связанную конфигурацию вместе. Имейте в виду, что в ключах принимаются только символы нижнего регистра ; символы верхнего регистра не допускаются.

Например, чтобы сохранить идентификатор клиента и ключ API для «Некоторой службы», вы можете запустить:

firebase functions:config:set someservice.key="THE API KEY" someservice.id="THE CLIENT ID"

Получить текущую конфигурацию среды

Чтобы проверить, что в настоящее время хранится в конфигурации среды для вашего проекта, вы можете использовать firebase functions:config:get . Он выведет JSON примерно так:

{
  "someservice": {
    "key":"THE API KEY",
    "id":"THE CLIENT ID"
  }
}

Эта функциональность основана на Google Cloud Runtime Configuration API .

Используйте functions.config для доступа к конфигурации среды в функции.

Некоторая конфигурация автоматически предоставляется в зарезервированном пространстве имен firebase . Конфигурация среды доступна внутри вашей запущенной функции через functions.config() . Чтобы использовать приведенную выше конфигурацию, ваш код может выглядеть так:

const functions = require('firebase-functions');
const request = require('request-promise');

exports.userCreated = functions.database.ref('/users/{id}').onWrite(event => {
  let email = event.data.child('email').val();

  return request({
    url: 'https://someservice.com/api/some/call',
    headers: {
      'X-Client-ID': functions.config().someservice.id,
      'Authorization': `Bearer ${functions.config().someservice.key}`
    },
    body: {email: email}
  });
});

Используйте конфигурацию среды для инициализации модуля

Некоторые модули Node готовы без какой-либо настройки. Другие модули требуют дополнительной настройки для правильной инициализации. Мы рекомендуем хранить эту конфигурацию в переменных конфигурации среды, а не жестко кодировать ее. Это помогает сделать ваш код более переносимым, что позволяет открывать исходный код вашего приложения или легко переключаться между рабочей и промежуточной версиями.

Например, чтобы использовать модуль Slack Node SDK , вы можете написать следующее:

const functions = require('firebase-functions');
const IncomingWebhook = require('@slack/client').IncomingWebhook;
const webhook = new IncomingWebhook(functions.config().slack.url);

Перед развертыванием установите переменную конфигурации среды slack.url :

firebase functions:config:set slack.url=https://hooks.slack.com/services/XXX

Дополнительные команды среды

  • firebase functions:config:unset key1 key2 удаляет указанные ключи из конфига
  • firebase functions:config:clone --from <fromProject> клонирует среду другого проекта в текущий активный проект.

Автоматически заполняемые переменные среды

Существуют переменные среды, которые автоматически заполняются во время выполнения функций и в локально эмулируемых функциях. К ним относятся те, которые заполняются Google Cloud , а также переменная среды, специфичная для Firebase:

process.env.FIREBASE_CONFIG : предоставляет следующую информацию о конфигурации проекта Firebase:

{
  databaseURL: 'https://databaseName.firebaseio.com',
  storageBucket: 'projectId.appspot.com',
  projectId: 'projectId'
}

Эта конфигурация применяется автоматически при инициализации Firebase Admin SDK без аргументов. Если вы пишете функции на JavaScript, инициализируйте их так:

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

Если вы пишете функции на TypeScript, инициализируйте их так:

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

Если вам нужно инициализировать Admin SDK с конфигурацией проекта по умолчанию, используя учетные данные служебной учетной записи, вы можете загрузить учетные данные из файла и добавить их в FIREBASE_CONFIG следующим образом:

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

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