在伺服器環境使用遠端設定

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 上的容器化服務。

Firebase 用戶端 SDK 會擷取衍生自 Remote Config 範本的用戶端專屬設定,但伺服器端 Remote Config SDK 則不同,會從 Firebase 下載或擷取完整的 Remote Config 範本。伺服器可以評估每個傳入要求的範本,並使用自己的邏輯,以極低的延遲時間提供自訂回應。您可以使用條件,根據隨機百分比和自訂信號中定義的用戶端屬性,控制及自訂回應。

使用伺服器端 Remote Config,您可以:

  • 為在伺服器上執行或透過伺服器存取的應用程式定義設定參數,以便遠端設定 AI 模型參數和提示,以及其他整合功能,確保 API 金鑰安全無虞。
  • 根據環境或其他應用程式的變化,動態調整參數,例如更新 LLM 參數和模型端點。
  • 從遠端更新伺服器呼叫的 API,控管費用。
  • 為存取伺服器的用戶端即時產生自訂設定。
  • 記錄哪些用戶端收到參數值,並在 Cloud Functions for Firebase 中使用,做為授權驗證系統的一部分。

您可以在 Cloud Run、Cloud Functions for Firebase 或自行託管的伺服器環境中,部署伺服器端 Remote Config。

事前準備

請按照「將 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

使用 FirebaseOptions 和服務帳戶憑證,初始化 Firebase Admin SDK:

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

Go

初始化 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 後端伺服器的連線中斷,應用程式仍可順利執行。

舉例來說,如果您正在編寫管理生成式 AI 函式的伺服器應用程式,可以設定預設模型名稱、提示前導提示和生成式 AI 設定,如下所示:

參數名稱 說明 類型 預設值
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();
    

    如果您在 Cloud Functions for Firebase 中使用 Node.js,可以使用非同步 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

    使用 FirebaseRemoteConfig.getInstance() 初始化伺服器端 Remote Config 用戶端:

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

    或者,如果您使用 Java 搭配 Cloud Functions for Firebase,可以使用 getServerTemplate(),在一個步驟中初始化並載入範本:

    ServerTemplate template = rc.getServerTemplate();
    

    Go

    使用 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 格式,然後使用 InitServerTemplate 函式初始化這個 JSON 範本。

  2. 為確保應用程式在與 Remote Config 後端伺服器的連線中斷時仍能成功執行,請在應用程式中為每個參數新增預設值。

    Node.js

    在 initServerTemplate 或 getServerTemplate 範本函式中新增 defaultConfig 物件:

    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

    在 init_server_template 或 get_server_template 範本函式中新增 default_config 字典:

    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 函式擷取必要的伺服器範本。您可以使用 template.to_json 函式,將這個範本轉換為 JSON 格式。這個 JSON 範本可以儲存在本機,之後您可以使用 init_server_template 函式初始化這個 JSON 範本。

    Java

    在 getServerTemplate 函式中使用 KeysAndValues 新增 defaultConfig 物件:

    // 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();
    

    Go

    在 InitServerTemplate 或 GetServerTemplate 範本函式中新增 defaultConfig 對應:

    // 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();
    

    Go

    未套用任何條件時,請使用 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 範本中設定條件,並定義及提供所需的背景資訊值:

    • 如果使用百分比條件,請在範本評估函式中,新增要用於評估條件的隨機 ID (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 安裝 ID 或使用者 ID 設為隨機 ID,確保與伺服器聯絡的每位使用者都加入適當的隨機群組,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

    建立包含 randomizationId 和任何自訂信號的 KeysAndValues 情境,並傳遞至 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);
    

    Go

    將包含 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. 接下來,從評估過的設定物件中擷取所需的參數值。使用 getter 方法,將 Remote Config 的值轉換為預期格式。

    舉例來說,如果您在伺服器上實作 Agent Platform,並想變更模型和模型參數,可以設定 model_name 和 generation_config 的參數。以下是支援的 getter 方法,以及各平台存取 Remote Config 值的範例:

    Node.js

    支援的 getter 方法:

    • 布林值: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

    支援的 getter 方法:

    • 布林值: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

    支援的 getter 方法:

    • 布林值: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。

    Go

    支援的 getter 方法:

    • 布林值: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. 如果伺服器長時間執行 (而非無伺服器環境),請定期重新載入範本 (例如在 Node.js 中使用 setInterval,或在 Java 中使用 java.util.Timer),確認您從 Remote Config 伺服器擷取的是最新範本。

步驟 4:在 Remote Config 中設定伺服器專屬參數值

接著,建立伺服器 Remote Config 範本,並設定要在應用程式中使用的參數和值。

以下說明如何建立伺服器專屬的 Remote Config 範本:

  1. 在 Firebase 控制台中,依序前往「DevOps & Engagement」 >「遠端設定」 >「Parameters」(參數) 頁面。

  2. 在頁面頂端的「Client/Server」(用戶端/伺服器) 選取器中,選取「Server」(伺服器)。

  3. 定義 Remote Config 參數,其名稱和資料類型與您在應用程式中定義的參數相同,並提供值。擷取及評估範本,並將這些值指派給變數時,這些值會覆寫您在「設定伺服器應用程式」中設定的預設設定 (defaultConfig 或 default_config)。

  4. 您也可以視需要設定條件,將值持續套用至隨機樣本的執行個體,或您定義的自訂信號。如要進一步瞭解條件,請參閱「條件規則類型」。

  5. 新增完參數後,請按一下「發布變更」。

  6. 查看變更,然後再次按一下「發布變更」。

步驟 5:使用 Cloud Functions for Firebase 或 Cloud Run 部署

如果伺服器應用程式是輕量型且事件導向,建議您使用 Cloud Functions for Firebase 部署程式碼。舉例來說,假設您有一個應用程式,其中包含由生成式 AI API (例如 Google AI 或 Agent Platform) 提供的角色對話。在這種情況下,您可以將 LLM 服務邏輯託管在應用程式隨選呼叫的函式中。

如果您要建構伺服器算繪的網頁應用程式,App Hosting 支援熱門的網頁框架。

否則,建議您使用 Cloud Run。如要使用 Cloud Run 部署伺服器應用程式,請按照您所用語言的快速入門指南操作:

如要進一步瞭解 Cloud Run 和 Cloud Functions for Firebase 的最佳用途,請參閱「Cloud Functions for Firebase 與 Cloud Run:何時該使用其中一個」。

後續步驟