使用 Remote Config 对模板进行版本控制


使用服务器提示模板时,您可以更新给定模板的值,而无需发布新版应用。不过,由于对模板的任何更改几乎都会立即被应用的请求使用,因此您需要谨慎进行更改,以免导致应用崩溃或行为发生意外变化。

因此,如果您想进行更大幅度的更改或逐步推出更改,则不应更改生产代码中使用的模板。

我们建议您改用 Firebase Remote Config控制向模型发出的请求中使用的模板 ID 的值

借助 Firebase Remote Config,您可以在 Firebase 控制台中动态地远程更新应用中的参数值(例如模板 ID),而无需发布新版本的应用。此外,它还具有简化的功能和集成,可用于推出更改以及进行 A/B 测试。

本指南介绍了如何在应用中实现 Remote Config,特别是如何控制应用中使用的模板 ID

第 1 步:在 Firebase 控制台中设置参数值

创建一个 Remote Config 客户端模板,并配置一个 template_id 参数及其值,以便在应用中提取和使用。

  1. Firebase 控制台中打开您的 Firebase 项目,然后从导航菜单中展开运行并选择 Remote Config

  2. 确保从页面顶部的客户端/服务器选择器中选择客户端

  3. 点击创建配置(如果您之前使用过客户端模板,则点击添加参数)以开始使用客户端模板。

  4. 定义 template_id 参数:

    参数名称 说明 类型 默认值
    template_id 模板 ID。 字符串 my-first-template-v1-0-0
  5. 添加此参数后,点击发布更改。如果这不是新的 Remote Config 模板,请查看更改,然后再次点击发布更改

第 2 步:在应用中添加并初始化 Remote Config

在应用中添加 Remote Config 库并设置 Remote Config

Swift

Firebase AI Logic 设置过程中,您已将 Firebase SDK 添加到应用中,但还需要添加 Remote Config

  1. 在 Xcode 中打开项目,前往 File(文件)> Add Package Dependencies(添加软件包依赖项)

  2. 选择 firebase-ios-sdk,然后点击 Add package(添加软件包)。

  3. 在项目导航器中,依次选择您的应用 > Targets(目标)> 您的应用。

  4. General(常规)标签页中,滚动到 Frameworks, Libraries, and Embedded Content(框架、库和嵌入内容)。

  5. 点击 +,然后选择 FirebaseRemoteConfig,接着点击 Add(添加)。

  6. FirebaseRemoteConfig 导入项添加到您的代码中:

    import FirebaseRemoteConfig 
  7. 在应用的适当类中,初始化 Firebase 并将 Remote Config 添加到您的主应用逻辑中。

    在此处,您将 Remote ConfigRemote Config 实时监听器作为导入项添加,以便应用可以实时提取新值,并添加最小提取间隔:

    let remoteConfig = RemoteConfig.remoteConfig() let settings = RemoteConfigSettings() settings.minimumFetchInterval = 3600 remoteConfig.configSettings = settings 

Kotlin

  1. Remote Config 依赖项添加到您的模块(应用级)Gradle 文件(通常是 app/build.gradle.ktsapp/build.gradle)中:

    dependencies {  implementation(platform("com.google.firebase:firebase-bom:34.6.0"))  implementation("com.google.firebase:firebase-ai")  implementation("com.google.firebase:firebase-config")  // ... other dependencies } 
  2. Remote Config 添加到您的主应用逻辑中。在这里,您将初始化 Remote Config 并添加最小提取间隔:

    val remoteConfig: FirebaseRemoteConfig = Firebase.remoteConfig val configSettings = remoteConfigSettings { minimumFetchIntervalInSeconds = 3600 } remoteConfig.setConfigSettingsAsync(configSettings) 

Java

  1. Remote Config 依赖项添加到您的模块(应用级)Gradle 文件(通常是 app/build.gradle.ktsapp/build.gradle)中:

    dependencies {  implementation(platform("com.google.firebase:firebase-bom:34.6.0"))  implementation("com.google.firebase:firebase-ai")  implementation("com.google.firebase:firebase-config")  // ... other dependencies } 
  2. Remote Config 添加到您的主应用逻辑中。在这里,您将初始化 Remote Config 并添加最小提取间隔:

    FirebaseRemoteConfig mFirebaseRemoteConfig = FirebaseRemoteConfig.getInstance(); FirebaseRemoteConfigSettings configSettings = new FirebaseRemoteConfigSettings.Builder()  .setMinimumFetchIntervalInSeconds(3600)  .build(); mFirebaseRemoteConfig.setConfigSettingsAsync(configSettings); 

Web

  1. 在文本编辑器中打开您的代码,然后导入 Remote Config

    import { getRemoteConfig } from 'firebase/remote-config'; 
  2. 在主要函数中,在 Firebase 应用针对 Firebase AI Logic SDK 进行初始化后,初始化 Remote Config

     // Initialize Remote Config and get a reference to the service  const remoteConfig = getRemoteConfig(app); 
  3. 设置最小提取间隔:

    remoteConfig.settings.minimumFetchIntervalMillis = 3600000; 

Dart

  1. 在您的 Flutter 项目目录中,使用以下命令安装并添加 Remote Config

    flutter pub add firebase_remote_config 
  2. 打开 ./lib/main.dart,将相应导入项添加在您添加的其他导入项后面以支持 Firebase AI Logic

    import 'package:firebase_vertexai/firebase_ai.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_remote_config/firebase_remote_config.dart'; 
  3. _modelName 变量添加到您的应用中,以便您稍后可以使用它:

    late final String _modelName; late final String _systemInstructions; late final String _prompt; 
  4. 获取 Remote Config 对象实例,并设置最小提取间隔以实现频繁刷新。请务必在 Firebase 初始化之后添加此内容。

     final remoteConfig = FirebaseRemoteConfig.instance;  await remoteConfig.setConfigSettings(RemoteConfigSettings(  fetchTimeout: const Duration(seconds: 3600),  minimumFetchInterval: const Duration(seconds: 3600),  )); 

Unity

  1. 按照这些说明Remote Config 添加到您的 Unity 项目。

  2. 获取 Remote Config 对象实例,并设置最小提取间隔以实现频繁刷新。请务必在 Firebase 初始化之后添加此内容。

    var remoteConfig = FirebaseRemoteConfig.DefaultInstance; const int MillisecondsPerSecond = 1000; await remoteConfig.SetConfigSettingsAsync(new ConfigSettings() {  FetchTimeoutInMilliseconds = 3600 * MillisecondsPerSecond,  MinimumFetchIntervalInMilliseconds = 3600 * MillisecondsPerSecond }); 

第 3 步:设置应用内参数值

您应在 Remote Config 对象中设置应用内默认参数值。这可确保您的应用即使无法从 Remote Config 服务中提取值,也能按预期运行。

Swift

  1. Firebase 控制台中,打开 Remote Config

  2. 参数标签页中,打开菜单,然后选择下载默认值

  3. 看到提示时,启用 .plist (iOS),然后点击下载文件

  4. 将该文件保存在应用目录中。

  5. 在 Xcode 中,右键点击您的应用,然后选择Add Files(添加文件)

  6. 选择 remote_config_defaults.plist,然后点击 Add(添加)。

  7. 更新应用代码以引用默认文件:

    // Set default values for Remote Config parameters. remoteConfig.setDefaults(fromPlist: "remote_config_defaults") 

Kotlin

  1. Firebase 控制台中,打开 Remote Config

  2. 参数标签页中,打开菜单,然后选择下载默认值

  3. 看到提示时,启用 .xml (Android),然后点击下载文件

  4. 将该文件保存在应用的 XML 资源目录中。

  5. 更新主 Activity 文件,以便在您以前添加的 configSettings 后面添加默认值:

    // Set default values for Remote Config parameters. remoteConfig.setDefaultsAsync(R.xml.remote_config_defaults) 

Java

  1. Firebase 控制台中,打开 Remote Config

  2. 参数标签页中,打开菜单,然后选择下载默认值

  3. 看到提示时,启用 .xml (Android),然后点击下载文件

  4. 将该文件保存在应用的 XML 资源目录中。

  5. 更新主 Activity 文件,以便在您以前添加的 configSettings 后面添加默认值:

    // Set default values for Remote Config parameters. mFirebaseRemoteConfig.setDefaultsAsync(R.xml.remote_config_defaults); 

Web

您可以直接在代码中设置模型名称的默认值:

// Set default values for Remote Config parameters. remoteConfig.defaultConfig = {  template_id: 'my-first-template-v1-0-0', }; 

Dart

您可以直接在代码中设置模型名称的默认值:

// Set default values for Remote Config parameters. remoteConfig.setDefaults(const {  "template_id": "my-first-template-v1-0-0" }); 

Unity

您可以直接在代码中设置模型名称的默认值:

// Set default values for Remote Config parameters. await remoteConfig.SetDefaultsAsync(  new System.Collections.Generic.Dictionary<string, object>() {  { "template_id", "my-first-template-v1-0-0" }  } ); 

第 4 步:提取并激活值

为模型名称设置默认值后,添加以下内容以提取并激活值。

Swift

// Fetch and activate Remote Config values remoteConfig.fetchAndActivate { status, error in  if let error = error {  print("Error fetching Remote Config: \(error.localizedDescription)")  } } 

每当发布新的 Remote Config 模板时,这应该更新 Remote Config 对象。

Kotlin

// Fetch and activate Remote Config values remoteConfig.fetchAndActivate()  .addOnCompleteListener(this) { task ->  if (task.isSuccessful) {  val updated = task.result  Log.d(TAG, "Remote Config values fetched and activated: $updated")  } else {  Log.e(TAG, "Error fetching Remote Config", task.exception)  }  } 

Java

 // Fetch and activate Remote Config values  mFirebaseRemoteConfig.fetchAndActivate()  .addOnCompleteListener(this, new OnCompleteListener<Boolean>() {  @Override  public void onComplete(@NonNull Task<Boolean> task) {  if (task.isSuccessful()) {  boolean updated = task.getResult();  Log.d(TAG, "Config params updated: " + updated);  } else {  Log.e(TAG, "Error fetching Remote Config", task.exception)  }  }  }); 

Web

  1. getValuefetchAndActivate 添加到导入项中:

    import { getValue, fetchAndActivate } from 'firebase/remote-config'; 
  2. 找到指定模型名称默认值的代码。 紧接着在该代码块之后,添加以下代码以提取并激活配置,并将提取的值分配给 templateID 常量。

    // Fetch and activate Remote Config. try {  await fetchAndActivate(remoteConfig); } catch(err) {  console.error('Remote Config fetch failed', err); } console.log('Remote Config fetched.'); // Assign Remote Config values. const templateID = getValue(remoteConfig, 'template_id').asString(); 

Dart

// Fetch and activate Remote Config. remoteConfig.fetchAndActivate(); // Assign Remote Config values. String? _templateID = remoteConfig.getString("template_id"); 

Unity

// Fetch and activate Remote Config values. await remoteConfig.FetchAndActivateAsync(); 

第 5 步:添加实时 Remote Config 监听器

为应用添加实时 Remote Config 监听器,以确保您对 Remote Config 模板所做的更改在更新后立即传播到客户端。

每当参数值更改时,以下代码会更新 Remote Config 对象。

Swift

// Add real-time Remote Config remoteConfig.addOnConfigUpdateListener { configUpdate, error in  guard let configUpdate = configUpdate, error == nil else {  print("Error listening for config updates: \(error?.localizedDescription ?? "No error available")")  return  }  print("Updated keys: \(configUpdate.updatedKeys)")  remoteConfig.activate { changed, error in  guard error == nil else {  print("Error activating config: \(error?.localizedDescription ?? "No error available")")  return  }  print("Activated config successfully")  } } 

Kotlin

或者,您也可以在 addOnCompleteListener 激活中配置操作:

 // Add a real-time Remote Config listener  remoteConfig.addOnConfigUpdateListener(object : ConfigUpdateListener {  override fun onUpdate(configUpdate : ConfigUpdate) {  Log.d(ContentValues.TAG, "Updated keys: " + configUpdate.updatedKeys);  remoteConfig.activate().addOnCompleteListener {  // Optionally, add an action to perform on update here.  }  }  override fun onError(error : FirebaseRemoteConfigException) {  Log.w(ContentValues.TAG, "Config update error with code: " + error.code, error)  }  } 

Java

或者,您也可以在 addOnCompleteListener 激活中配置操作:

 // Add a real-time Remote Config listener  remoteConfig.addOnConfigUpdateListener(new ConfigUpdateListener() {  @Override  public void onUpdate(ConfigUpdate configUpdate) {  Log.d(ContentValues.TAG, "Updated keys: " + configUpdate.getUpdatedKeys());  remoteConfig.activate().addOnCompleteListener(new OnCompleteListener<Boolean>() {  @Override  public void onComplete(@NonNull Task<Boolean> task) {  // Optionally, add an action to perform on update here.  }  });  }  @Override  public void onError(FirebaseRemoteConfigException error) {  Log.w(ContentValues.TAG, "Config update error with code: " + error.getCode(), error);  }  }); 

Web

Web 应用不支持实时 Remote Config 监听器

Dart

// Add a real-time Remote Config listener remoteConfig.onConfigUpdated.listen((event) async {  await remoteConfig.activate(); }); 

Unity

// Add a real-time Remote Config listener to automatically update whenever // a new template is published. // Note: the parameters can be anonymous as they are unused. remoteConfig.OnConfigUpdateListener += (_, _) => {  remoteConfig.ActivateAsync(); }; 

第 6 步:更新 Gemini API 请求以使用 Remote Config

点击您的 Gemini API 提供商,以查看此页面上特定于提供商的内容和代码。

现在,Remote Config 已完全配置,可更新代码以将硬编码值替换为来自 Remote Config 的值。

Swift

import FirebaseAI let templateID = remoteConfig.configValue(forKey: "template_id").stringValue let model = FirebaseAI.firebaseAI(backend: .googleAI()).templateGenerativeModel() let customerName = "Jane" // When making the `generateContent` call, source the template ID value from Remote Config let response = try await model.generateContent(  templateID: templateID,  // Provide the values for any input variables required by your template.  inputs: [  "customerName": customerName  ] ) // ... 

Kotlin

// ... val model = Firebase.ai(backend = GenerativeBackend.googleAI()).templateGenerativeModel() val customerName = "Jane" // When making the `generateContent` call, source the template ID value from Remote Config val response = model.generateContent(  remoteConfig.getString("template_id"),  // Provide the values for any input variables required by your template.  mapOf(  "customerName" to customerName  ) ) val text = response.text println(text) 

Java

// ... TemplateGenerativeModel ai = FirebaseAI.getInstance()  .templateGenerativeModel(null /* Request Options */); TemplateGenerativeModelFutures model = TemplateGenerativeModelFutures.from(ai); String customerName = "Jane"; // When making the `generateContent` call, source the template ID value from Remote Config Future<GenerateContentResponse> response = model.generateContent(  remoteConfig.getString("template_id"),  // Provide the values for any input variables required by your template.  mapOf("customerName", customerName) ); addCallback(response,  new FutureCallback<GenerateContentResponse>() {  public void onSuccess(GenerateContentResponse result) {  System.out.println(result.getText());  }  public void onFailure(Throwable t) {  reportError(t);  }  } executor); // ... 

Web

// ... const ai = getAI(firebaseApp, { backend: new GoogleAIBackend() }); const model = getTemplateGenerativeModel(ai); const templateID = getValue(remoteConfig, 'template_id').asString(); const customerName = 'Jane'; // When making the `generateContent` call, source the template ID value from Remote Config const result = await model.generateContent(  templateID,  // Provide the values for any input variables required by your template  {  customerName: customerName,  } ); // ... 

Dart

// ... final model = FirebaseAI.googleAI().templateGenerativeModel(); final templateID = remoteConfig.getString("template_id"); final customerName = 'Jane'; // When making the `generateContent` call, source the template ID value from Remote Config var response = await model.generateContent(  templateID,  // Provide the values for any input variables required by your template  inputs: {  'customerName': customerName,  }, ); // ... 

Unity

// ... var ai = FirebaseAI.GetInstance(FirebaseAI.Backend.GoogleAI()); var templateID = remoteConfig.GetValue("template_id").StringValue; var model = ai.GetTemplateGenerativeModel(); var customerName = "Jane"; try {  // When making the `generateContent` call, source the template ID value from Remote Config  var response = await model.GenerateContentAsync(  templateID,  // Provide the values for any input variables required by your template  new Dictionary<string, object>  {  { "customerName", customerName },  }  );  Debug.Log($"Response Text: {response.Text}"); } catch (Exception e) {  Debug.LogError($"An error occurred: {e.Message}"); } // ... 

第 7 步:运行应用

构建并运行应用,并验证其能否正常运行。在 Firebase 控制台的 Remote Config 页面中对配置进行更改,发布更改,然后验证结果。

后续步骤