Как использовать Remote Config в серверных средах

Firebase Remote Config поддерживает конфигурацию на стороне сервера с помощью Firebase Admin SDK для Node.js (версии 12.1.0 и выше), Python (версии 6.7.0 и выше), Java (версии 9.7.0 и выше) и Go (версии 4.17.0 и выше).

Эта функция позволяет динамически управлять поведением и конфигурацией серверных приложений с помощью Remote Config. Это включает бессерверные реализации, такие как Cloud Functions for Firebase, и контейнеризованные сервисы на Cloud Run.

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

С помощью Remote Config на стороне сервера вы можете:

  • Определите параметры конфигурации для приложений, работающих на вашем сервере или доступных через него. Это позволит использовать такие сценарии, как удаленная настройка параметров и подсказок модели ИИ, а также другие интеграции, чтобы обеспечить безопасность ключей API.
  • Динамически корректируйте параметры в ответ на изменения в вашей среде или другие изменения в приложении, например обновляйте параметры LLM и конечные точки модели.
  • Контролируйте расходы, удаленно обновляя API, которые вызывает ваш сервер.
  • Создавайте собственные конфигурации на лету для клиентов, которые обращаются к вашему серверу.
  • Записывайте, какие клиенты получили значение параметра, и используйте эти данные в Cloud Functions for Firebase в рамках системы проверки прав.

Вы можете развернуть серверный контейнер Remote Config в Cloud Run, Cloud Functions for Firebase или на собственном сервере.

Подготовка

Следуйте инструкциям в статье Как добавить Firebase Admin SDK на сервер, чтобы создать проект Firebase, настроить сервисный аккаунт и добавить Firebase Admin SDK на сервер. Убедитесь, что вы используете поддерживаемую версию Admin SDK для своей платформы:

  • Node.js: Firebase Admin Node.js SDK версии 12.1.0 или более поздней.
  • Python: Firebase Admin Python SDK версии 6.7.0 или более поздней.
  • Java: Firebase Admin Java SDK версии 9.7.0 или более поздней.
  • Go: Firebase Admin Go SDK версии 4.17.0 или более поздней.

Шаг 1. Инициализируйте Firebase Admin SDK и авторизуйте запросы к API

Если вы инициализируете Admin SDK без параметров, SDK использует стандартные учетные данные приложения Google и считывает параметры из переменной среды GOOGLE_APPLICATION_CREDENTIALS. Инициализируйте SDK и настройте Remote Config для своей платформы:

Node.js

Импортируйте initializeApp и getRemoteConfig, а затем инициализируйте экземпляр приложения Firebase:

import { initializeApp } from "firebase-admin/app";
import { getRemoteConfig } from "firebase-admin/remote-config";

// Initialize Firebase
const firebaseApp = initializeApp();

Python

Импортируйте firebase_admin (а также asyncio и json для асинхронной загрузки шаблонов и синтаксического анализа JSON), а затем инициализируйте приложение:

import firebase_admin
import asyncio
import json

firebase_admin.initialize_app()

Java

Инициализируйте Firebase Admin SDK с помощью FirebaseOptions и учетных данных сервисного аккаунта:

// Initialize the Firebase Admin SDK
FirebaseOptions options = new FirebaseOptions.Builder()
    .setCredentials(GoogleCredentials.fromStream(serviceAccount))
    .build();
FirebaseApp.initializeApp(options);

Проложить маршрут

Инициализируйте приложение Firebase и создайте экземпляр клиента RemoteConfig:

ctx := context.Background()

// Initialize Firebase
app, err := firebase.NewApp(ctx, nil)
if err != nil {
    log.Fatalln("Error initializing app:", err)
}

remoteConfig, err := app.RemoteConfig(ctx)
if err != nil {
    log.Fatalln("Error initializing remote config client:", err)
}

Шаг 2. Определите значения параметров по умолчанию для серверного приложения

Определите переменные в приложении, которые вы хотите динамически обновлять с помощью Remote Config. Затем определите, какие переменные должны быть заданы в приложении по умолчанию и какие значения им следует присвоить. Это гарантирует, что ваше приложение будет работать успешно, даже если его подключение к бэкенд-серверу Remote Config будет прервано.

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

Название параметра Описание Тип Значение по умолчанию
model_name Название модели в API Строка gemini-3.8-flash
preamble_prompt Запрос, который будет добавлен перед запросом пользователя Строка I'm a developer who wants to learn about Firebase and you are a helpful assistant who knows everything there is to know about Firebase!
generation_config Параметры, которые нужно отправить модели JSON {"stopSequences": ["I hope this helps"], "maxOutputTokens": 512}

Шаг 3. Настройте серверное приложение

Определив, какие параметры вы хотите использовать с Remote Config, настройте приложение так, чтобы оно задавало значения по умолчанию, получало шаблон Remote Config для сервера и оценивало его значения.

  1. Откройте и загрузите серверный шаблон Remote Config.

    Node.js

    Инициализируйте шаблон сервера с помощью initServerTemplate() и вызовите load(), чтобы получить шаблон из бэкенда:

    // Initialize server-side Remote Config
    const rc = getRemoteConfig(firebaseApp);
    const template = rc.initServerTemplate();
    
    // Load Remote Config
    await template.load();
    

    Если вы используете Node.js в Cloud Functions for Firebase, то можете применить асинхронную функцию getServerTemplate(), чтобы инициализировать и загрузить шаблон за один шаг:

    // Initialize server-side Remote Config
    const rc = getRemoteConfig(firebaseApp);
    const template = await rc.getServerTemplate();
    

    Python

    Инициализируйте шаблон сервера с помощью init_server_template() и вызовите load(), чтобы получить шаблон из бэкенда:

    from firebase_admin import remote_config
    
    # Initialize server-side Remote Config
    template = remote_config.init_server_template()
    
    # Load the template from the backend
    asyncio.run(template.load())
    

    Если вы используете Python с Cloud Functions for Firebase, то можете инициализировать и загрузить шаблон за один шаг с помощью асинхронной функции get_server_template():

    # Initialize server-side Remote Config
    template = await remote_config.get_server_template()
    

    Java

    Инициализируйте клиент Remote Config на стороне сервера с помощью FirebaseRemoteConfig.getInstance():

    // Initialize server-side Remote Config client
    FirebaseRemoteConfig rc = FirebaseRemoteConfig.getInstance();
    

    Если вы используете Java с Cloud Functions for Firebase, то можете инициализировать и загрузить шаблон за один шаг с помощью getServerTemplate():

    ServerTemplate template = rc.getServerTemplate();
    

    Проложить маршрут

    Инициализируйте шаблон сервера с помощью InitServerTemplate() и вызовите Load(), чтобы получить шаблон из бэкенда:

    // Initialize server-side Remote Config
    defaultConfig := make(map[string]any)
    templateDataJSON := ""
    template, err := remoteConfig.InitServerTemplate(defaultConfig, templateDataJSON)
    if err != nil {
        log.Fatalln("Error initializing server template:", err)
    }
    
    // Load Remote Config
    err = template.Load(ctx)
    if err != nil {
        log.Fatalln("Error fetching server template:", err)
    }
    

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

  2. Чтобы приложение работало, даже если связь с бэкенд-сервером Remote Config прервется, добавьте значения по умолчанию для каждого параметра.

    Node.js

    Добавьте объект defaultConfig в функцию шаблона initServerTemplate или getServerTemplate:

    const template = rc.initServerTemplate({
      defaultConfig: {
        model_name: "gemini-3.8-flash",
        generation_config: '{"stopSequences": [], "maxOutputTokens": 512}',
        preamble_prompt: "I'm a developer who wants to learn about Firebase and you are a helpful assistant who knows everything there is to know about Firebase!"
      },
    });
    
    // Load Remote Config
    await template.load();
    

    Python

    Добавьте словарь default_config в функцию шаблона init_server_template или get_server_template:

    template = remote_config.init_server_template({
      'default_config': {
        'model_name': "gemini-3.8-flash",
        'generation_config': '{"stopSequences": [], "maxOutputTokens": 512}',
        'preamble_prompt': "I'm a developer who wants to learn about Firebase and you are a helpful assistant who knows everything there is to know about Firebase!"
      },
    })
    
    # Load Remote Config
    asyncio.run(template.load())
    

    Другой способ инициализации шаблона – использование функции get_server_template для получения нужного шаблона сервера. Вы можете преобразовать этот шаблон в формат JSON с помощью функции template.to_json. Этот шаблон JSON можно хранить локально, а затем инициализировать с помощью функции init_server_template.

    Java

    Добавьте объект defaultConfig с помощью KeysAndValues в функцию getServerTemplate:

    // Initialize default config using KeysAndValues
    KeysAndValues defaultConfig = new KeysAndValues.Builder()
                                      .put("rc_param_1", "default value 1")
                                      .put("rc_param_2", "default value 2")
                                      .build();
    ServerTemplate template = rc.getServerTemplate(defaultConfig);
    

    Вы также можете передать шаблон по умолчанию, сохраненный в кеше, при инициализации Remote Config. Он будет использоваться, даже если подключение к серверу Remote Config прервется.

    String templateDataJSON = "{}"; // add your default template as JSON
    ServerTemplate template = rc.serverTemplateBuilder()
                        .defaultConfig(defaultConfig)
                        .cachedTemplate(templateDataJSON)
                        .build();
    

    Проложить маршрут

    Добавьте карту defaultConfig в функцию шаблона InitServerTemplate или GetServerTemplate:

    // Initialize server-side Remote Config
    defaultConfig := make(map[string]any)
    defaultConfig["model_name"] = "gemini-3.8-flash"
    
    // Assume the type generationConfig has been defined
    defaultConfig["generation_config"] = &generationConfig{
        StopSequences:   []string{"I hope this helps"},
        MaxOutputTokens: 512,
    }
    
    defaultConfig["preamble_prompt"] = "I'm a developer who wants to learn about Firebase and you are a helpful assistant who knows everything there is to know about Firebase!"
    
    templateDataJSON := ""
    template, err := remoteConfig.InitServerTemplate(defaultConfig, templateDataJSON)
    if err != nil {
        log.Fatalln("Error initializing server template:", err)
    }
    
    // Load Remote Config
    err = template.Load(ctx)
    if err != nil {
        log.Fatalln("Error fetching server template:", err)
    }
    
  3. После загрузки шаблона оцените его, чтобы импортировать параметры и значения:

    Node.js

    Используйте template.evaluate():

    // Add template parameters to config
    const config = template.evaluate();
    

    Python

    Используйте template.evaluate():

    # Add template parameters to config
    config = template.evaluate()
    

    Java

    Используйте template.evaluate():

    // Add template parameters to config
    ServerConfig config = template.evaluate();
    

    Проложить маршрут

    Используйте template.Evaluate() с пустым контекстом оценки, если условия не применяются:

    // An empty evaluation context means no conditions are applied.
    evaluationContext := make(map[string]any)
    config, err := template.Evaluate(evaluationContext)
    if err != nil {
        log.Fatalln("Error evaluating template:", err)
    }
    
  4. Если вы задали условия в шаблоне Remote Config, вы можете определить и указать нужные значения контекста:

    • Если вы используете условия с процентами, добавьте идентификатор рандомизации (randomizationId, randomization_id или randomizationID), который хотите использовать для оценки условий в функции оценки шаблона.
    • Если вы используете специальные сигналы, определите атрибуты и их значения. Пользовательские сигналы доступны в Firebase Admin Node.js SDK версии 12.5.0 и выше, Python SDK версии 6.7.0 и выше, Java SDK версии 9.7.0 и выше и Go SDK версии 4.17.0 и выше.

    Например, в качестве идентификатора рандомизации можно задать идентификатор установки Firebase или идентификатор пользователя. Это позволит добавлять каждого пользователя, который обращается к вашему серверу, в нужную группу рандомизации. В качестве специальных сигналов можно задать version для таргетинга на определенные версии клиента и platform для таргетинга на клиентские платформы.

    Подробнее о типах правил для условий…

    Node.js

    Передайте объект контекста оценки, содержащий randomizationId и любые пользовательские сигналы, в template.evaluate():

    // Add template parameters to `config`. Evaluates the
    // template and returns the parameter value assigned to
    // the group assigned to the {randomizationId} and version.
    const config = template.evaluate({
      randomizationId: "2ac93c28-c459-4760-963d-a3974ec26c04",
      version: "1.0",
      platform: "Android"
    });
    

    Python

    Передайте словарь, содержащий randomization_id и любые специальные сигналы, в template.evaluate():

    # Add template parameters to `config`. Evaluates the
    # template and returns the parameter value assigned to
    # the group assigned to the {randomization_id} and version.
    config = template.evaluate({
      'randomization_id': "2ac93c28-c459-4760-963d-a3974ec26c04",
      'version': "1.0",
      'platform': "Android"
    })
    

    Java

    Создайте контекст KeysAndValues, содержащий randomizationId и любые пользовательские сигналы, и передайте его в template.evaluate():

    // Add custom signals and randomizationId
    KeysAndValues context = new KeysAndValues.Builder()
                                    .put("custom_signal_key", "99")
                                    .put("randomizationId", "2ac93c28")
                                    .build();
    
    // Evaluate the template with signals
    ServerConfig config = template.evaluate(context);
    

    Проложить маршрут

    Передайте карту контекста оценки, содержащую randomizationID и любые пользовательские сигналы, в template.Evaluate():

    // Add template parameters to `config`. Evaluates the
    // template and returns the parameter value assigned to
    // the group assigned to the {randomizationID}, version, and platform.
    evaluationContext := make(map[string]any)
    evaluationContext["randomizationID"] = "2ac93c28-c459-4760-963d-a3974ec26c04"
    evaluationContext["version"] = "1.0"
    evaluationContext["platform"] = "Android"
    
    config, err := template.Evaluate(evaluationContext)
    if err != nil {
        log.Fatalln("Error evaluating template:", err)
    }
    
  5. Затем извлеките нужные значения параметров из объекта конфигурации. Используйте методы получения, чтобы преобразовать значения из Remote Config в ожидаемый формат.

    Например, если вы реализуете Agent Platform на сервере и хотите изменить модель и ее параметры, вы можете настроить параметры для model_name и generation_config. Ниже приведены поддерживаемые методы получения и примеры доступа к значениям Remote Config для каждой платформы.

    Node.js

    Поддерживаемые методы получения:

    • Логическое значение: getBoolean
    • Объект: getValue
    • Номер: getNumber
    • Строка: getString

    // Replace defaults with values from Remote Config.
    const generationConfig =
      JSON.parse(
        config.getString('generation_config'));
    
    const is_ai_enabled = config.getBoolean('is_ai_enabled');
    
    const model = config.getString('model_name');
    
    // Generates a prompt comprised of the Remote Config
    // parameter and prepends it to the user prompt
    const prompt = `${config.getString('preamble_prompt')} ${req.query.prompt}`;
    

    Python

    Поддерживаемые методы получения:

    • Логическое значение: get_bool
    • Целое число: get_int
    • Смещение: get_float
    • Строка: get_string
    • Источник значения: get_value_source

    # Replace defaults with values from Remote Config.
    generation_config = json.loads(config.get_string('generation_config'))
    is_ai_enabled = config.get_bool('is_ai_enabled')
    model = config.get_string('model_name')
    
    # Generates a prompt comprised of the Remote Config
    # parameter and prepends it to the user prompt.
    prompt = f"{config.get_string('preamble_prompt')}{req.args.get('prompt')}"
    

    Java

    Поддерживаемые методы получения:

    • Логическое значение: getBoolean
    • Строка: getString
    • Двойной: getDouble
    • Полный (getLong)
    • Источник значения: getValueSource

    // Get the model name
    String modelName = config.getString("model_name");
    // Get the origin of value assigned to param
    ValueSource modelNameSource = config.getValueSource("model_name");
    

    Метод getValueSource возвращает ValueSource, указывающий, является ли источником значения параметра STATIC, REMOTE или DEFAULT.

    Проложить маршрут

    Поддерживаемые методы получения:

    • Логическое значение: GetBoolean
    • Целое число: GetInt
    • Смещение: GetFloat
    • Строка: GetString
    • Источник значения: GetValueSource

    // Replace defaults with values from Remote Config.
    
    // Assume the type generationConfig has been defined
    var genConfig generationConfig
    err = json.Unmarshal([]byte(config.GetString("generation_config")), &genConfig)
    if err != nil {
        log.Fatalln("Error unmarshaling generation config:", err)
    }
    model := config.GetString("model_name")
    
    // Parameter created on the console
    isAIEnabled := config.GetBoolean("is_ai_enabled")
    
    // Generates a prompt comprised of the Remote Config
    // parameter and prepends it to the user prompt (assume it is extracted from the request body)
    userPrompt := "What is Remote Config?"
    prompt := fmt.Sprintf("%s %s", config.GetString("preamble_prompt"), userPrompt)
    
  6. Если ваш сервер работает постоянно, а не в бессерверной среде, периодически перезагружайте шаблон (например, с помощью setInterval в Node.js или java.util.Timer в Java), чтобы получать самую актуальную версию шаблона с сервера Remote Config.

Шаг 4. Задайте значения параметров для сервера в Remote Config

Затем создайте шаблон сервера Remote Config и настройте параметры и значения, которые будут использоваться в приложении.

Чтобы создать шаблон Remote Config для сервера, выполните следующие действия:

  1. В консоли Firebase перейдите на страницу DevOps & Engagement (DevOps и взаимодействие) > Remote Config (Удаленная конфигурация) > Parameters (Параметры).

  2. В селекторе Клиент/сервер в верхней части страницы выберите Сервер.

  3. Определите Remote Config параметров с теми же названиями и типами данных, что и у параметров, которые вы определили в приложении, и укажите значения. Эти значения переопределят настройки по умолчанию (defaultConfig или default_config), заданные в разделе Настройка серверного приложения, когда вы получите и оцените шаблон и назначите эти значения переменным.

  4. При необходимости задайте условия, чтобы постоянно применять значения к случайной выборке экземпляров или заданных вами пользовательских сигналов. Подробнее о типах правил условий…

  5. Добавив параметры, нажмите Опубликовать изменения.

  6. Проверьте изменения и снова нажмите Опубликовать изменения.

Шаг 5. Выполните развертывание с помощью Cloud Functions for Firebase или Cloud Run

Если ваше серверное приложение невелико и управляется событиями, рекомендуем развернуть код с помощью Cloud Functions for Firebase. Например, у вас есть приложение, в котором диалоги персонажей генерируются с помощью API генеративного искусственного интеллекта (например, Google AI или Agent Platform). В этом случае вы можете разместить логику обслуживания LLM в функции, которую ваше приложение вызывает по запросу.

Если вы создаете веб-приложение с рендерингом на сервере, App Hosting поддерживает популярные веб-фреймворки.

В противном случае вы можете использовать Cloud Run. Чтобы развернуть серверное приложение с помощью Cloud Run, следуйте краткому руководству для вашего языка:

Дальнейшие действия