Используйте Remote Config в серверных средах

Firebase Remote Config поддерживает настройку на стороне сервера с использованием Firebase Admin SDK для Node.js (v12.1.0+), Python (v6.7.0+), Java (v9.7.0+) и Go (v4.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 v12.1.0+
  • Python : Firebase Admin Python SDK v6.7.0+
  • Java : Firebase Admin Java SDK v9.7.0+
  • Go : Firebase Admin Go SDK v4.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-2.0-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"], "temperature": 0.7, "maxOutputTokens": 512, "topP": 0.1, "topK": 20}

Шаг 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-pro",
        generation_config: '{"stopSequences": [], "temperature": 0.7, "maxOutputTokens": 512, "topP": 0.1, "topK": 20}',
        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-pro",
        'generation_config': '{"stopSequences": [], "temperature": 0.7, "maxOutputTokens": 512, "topP": 0.1, "topK": 20}',
        '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-2.0-flash"
    
    // Assume the type generationConfig has been defined
    defaultConfig["generation_config"] = &generationConfig{
        StopSequences:   []string{"I hope this helps"},
        Temperature:     0.7,
        MaxOutputTokens: 512,
        TopP:            0.9,
        TopK:            30,
    }
    
    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

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

    # 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);
    

    Идти

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

    // 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
    • Float: 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
    • Double: getDouble
    • Long: 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 > 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 , следуйте краткому руководству для вашего языка программирования:

Для получения дополнительной информации о наилучших вариантах использования Cloud Run и Cloud Functions for Firebase см. статью Cloud Functions for Firebase vs. Cloud Run : когда лучше использовать один из них» .

Следующие шаги