Join us in person and online for Firebase Summit on October 18, 2022. Learn how Firebase can help you accelerate app development, release your app with confidence, and scale with ease. Register now

以編程方式修改遠程配置

透過集合功能整理內容 你可以依據偏好儲存及分類內容。

本文檔描述瞭如何以編程方式讀取和修改一組 JSON 格式的參數和條件,稱為遠程配置模板。這允許您在客戶端應用程序可以使用客戶端庫獲取的後端進行模板更改。

使用本指南中描述的Remote Config REST APIAdmin SDK ,您可以繞過在 Firebase 控制台中管理模板,將遠程配置更改直接集成到您自己的流程中。例如,使用遠程配置後端 API,您可以:

  • 安排遠程配置更新。通過將 API 調用與 cron 作業結合使用,您可以定期更改遠程配置值。
  • 批量導入配置值,以便有效地從您自己的專有系統過渡到 Firebase 遠程配置。
  • 將 Remote Config 與 Cloud Functions for Firebase 結合使用,根據服務器端發生的事件更改應用中的值。例如,您可以使用遠程配置來推廣應用中的新功能,然後在檢測到足夠多的人與新功能進行交互後自動關閉該推廣。

    顯示遠程配置後端與自定義工具和服務器交互的圖表

本指南的以下部分描述了您可以使用遠程配置後端 API 執行的操作。要查看通過 REST API 執行這些任務的一些代碼,請參閱以下示例應用程序之一:

使用 Firebase Admin SDK 修改遠程配置

Admin SDK 是一組服務器庫,可讓您在特權環境中與 Firebase 交互。除了對遠程配置執行更新之外,Admin SDK 還支持生成和驗證 Firebase 身份驗證令牌、從實時數據庫讀取和寫入等等。要詳細了解 Admin SDK 先決條件和設置,請參閱將 Firebase Admin SDK 添加到您的服務器

在典型的遠程配置流程中,您可能會獲取當前模板,修改一些參數或參數組和條件,驗證模板,然後發布它。在進行這些 API 調用之前,您必須授權來自 SDK 的請求。

初始化 SDK 並授權 API 請求

當您在沒有參數的情況下初始化 Admin SDK 時,SDK 使用Google 應用程序默認憑據並從FIREBASE_CONFIG環境變量中讀取選項。如果FIREBASE_CONFIG變量的內容以{開頭,它將被解析為 JSON 對象。否則,SDK 假定該字符串是包含選項的 JSON 文件的名稱。

例如:

節點.js

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

爪哇

FileInputStream serviceAccount = new FileInputStream("service-account.json");
FirebaseOptions options = FirebaseOptions.builder()
        .setCredentials(GoogleCredentials.fromStream(serviceAccount))
        .build();
FirebaseApp.initializeApp(options);

獲取當前的遠程配置模板

使用遠程配置模板時,請記住它們是版本化的,並且每個版本從創建時間到您用更新替換它的時間都有一個有限的生命週期:90 天,總共限制 300 個存儲版本。有關詳細信息,請參閱模板和版本控制

您可以使用後端 API 以 JSON 格式獲取遠程配置模板的當前活動版本。

在 A/B 測試實驗中專門作為變體創建的參數和參數值不包含在導出的模板中。

獲取模板:

節點.js

function getTemplate() {
  var config = admin.remoteConfig();
  config.getTemplate()
      .then(function (template) {
        console.log('ETag from server: ' + template.etag);
        var templateStr = JSON.stringify(template);
        fs.writeFileSync('config.json', templateStr);
      })
      .catch(function (err) {
        console.error('Unable to get template');
        console.error(err);
      });
}

爪哇

Template template = FirebaseRemoteConfig.getInstance().getTemplateAsync().get();
// See the ETag of the fetched template.
System.out.println("ETag from server: " + template.getETag());

修改遠程配置參數

您可以通過編程方式修改和添加遠程配置參數和參數組。例如,對於名為“new_menu”的現有參數組,您可以添加一個參數來控制季節性信息的顯示:

節點.js

function addParameterToGroup(template) {
  template.parameterGroups['new_menu'].parameters['spring_season'] = {
    defaultValue: {
      useInAppDefault: true
    },
    description: 'spring season menu visibility.',
  };
}

爪哇

template.getParameterGroups().get("new_menu").getParameters()
        .put("spring_season", new Parameter()
                .setDefaultValue(ParameterValue.inAppDefault())
                .setDescription("spring season menu visibility.")
        );

API 允許您創建新參數和參數組,或修改默認值、條件值和描述。在所有情況下,您都必須在進行修改後顯式發布模板。

修改遠程配置條件

您可以以編程方式修改和添加遠程配置條件和條件值。例如,要添加一個新條件:

節點.js

function addNewCondition(template) {
  template.conditions.push({
    name: 'android_en',
    expression: 'device.os == \'android\' && device.country in [\'us\', \'uk\']',
    tagColor: 'BLUE',
  });
}

爪哇

template.getConditions().add(new Condition("android_en",
        "device.os == 'android' && device.country in ['us', 'uk']", TagColor.BLUE));

在所有情況下,您都必須在進行修改後顯式發布模板。

遠程配置後端 API 提供了幾個條件和比較運算符,您可以使用它們來更改應用程序的行為和外觀。要了解有關條件和這些條件支持的運算符的更多信息,請參閱條件表達式參考

驗證遠程配置模板

或者,您可以在發布更新之前對其進行驗證,如下所示:

節點.js

function validateTemplate(template) {
  admin.remoteConfig().validateTemplate(template)
      .then(function (validatedTemplate) {
        // The template is valid and safe to use.
        console.log('Template was valid and safe to use');
      })
      .catch(function (err) {
        console.error('Template is invalid and cannot be published');
        console.error(err);
      });
}

爪哇

try {
  Template validatedTemplate = FirebaseRemoteConfig.getInstance()
          .validateTemplateAsync(template).get();
  System.out.println("Template was valid and safe to use");
} catch (ExecutionException e) {
  if (e.getCause() instanceof FirebaseRemoteConfigException) {
    FirebaseRemoteConfigException rcError = (FirebaseRemoteConfigException) e.getCause();
    System.out.println("Template is invalid and cannot be published");
    System.out.println(rcError.getMessage());
  }
}

此驗證過程檢查錯誤,例如參數和條件的重複鍵、無效的條件名稱或不存在的條件或格式錯誤的 etag。例如,包含超過允許的鍵數(2000)的請求將返回錯誤消息, Param count too large

發布遠程配置模板

檢索模板並使用所需的更新對其進行修改後,您可以發布它。按照本節中的說明發布模板會將整個現有配置模板替換為更新的文件,並且為新的活動模板分配比它替換的模板大一號的版本號。

如有必要,您可以使用 REST API回滾到以前的版本。為了降低更新中出錯的風險,您可以在發布前進行驗證

遠程配置個性化和條件包含在下載的模板中,因此在嘗試發佈到其他項目時,請務必注意以下限制:

  • 個性化不能從一個項目導入到另一個項目。

    例如,如果您在項目中啟用了個性化並下載和編輯模板,則可以將其發佈到同一個項目,但不能將其發佈到不同的項目,除非您從模板中刪除個性化。

  • 條件可以從一個項目導入到另一個項目,但請注意,任何特定的條件值(如應用 ID 或受眾)在發布之前都應該存在於目標項目中。

    例如,如果您有一個 Remote Config 參數,該參數使用指定iOS平台值的條件,則可以將模板發佈到另一個項目,因為任何項目的平台值都是相同的。但是,如果它包含依賴於特定應用 ID 或目標項目中不存在的用戶受眾的條件,則驗證將失敗。

  • 如果您計劃發布的模板包含依賴 Google Analytics 的條件,則必須在目標項目中啟用 Analytics。

節點.js

function publishTemplate() {
  var config = admin.remoteConfig();
  var template = config.createTemplateFromJSON(
      fs.readFileSync('config.json', 'UTF8'));
  config.publishTemplate(template)
      .then(function (updatedTemplate) {
        console.log('Template has been published');
        console.log('ETag from server: ' + updatedTemplate.etag);
      })
      .catch(function (err) {
        console.error('Unable to publish template.');
        console.error(err);
      });
}

爪哇

try {
  Template publishedTemplate = FirebaseRemoteConfig.getInstance()
          .publishTemplateAsync(template).get();
  System.out.println("Template has been published");
  // See the ETag of the published template.
  System.out.println("ETag from server: " + publishedTemplate.getETag());
} catch (ExecutionException e) {
  if (e.getCause() instanceof FirebaseRemoteConfigException) {
    FirebaseRemoteConfigException rcError = (FirebaseRemoteConfigException) e.getCause();
    System.out.println("Unable to publish template.");
    System.out.println(rcError.getMessage());
  }
}

使用 REST API 修改遠程配置

本節介紹遠程配置 REST API 的主要功能,網址為https://firebaseremoteconfig.googleapis.com 。有關完整的詳細信息,請參閱API 參考

獲取訪問令牌以對 API 請求進行身份驗證和授權

Firebase 項目支持 Google服務帳戶,您可以使用它從您的應用服務器或受信任的環境中調用 Firebase 服務器 API。如果您在本地開發代碼或在本地部署應用程序,則可以使用通過此服務帳戶獲得的憑據來授權服務器請求。

要對服務帳號進行身份驗證並授權其訪問 Firebase 服務,您必須生成 JSON 格式的私鑰文件。

要為您的服務帳戶生成私鑰文件:

  1. 在 Firebase 控制台中,打開Settings > Service Accounts

  2. 單擊Generate New Private Key ,然後單擊Generate Key進行確認。

  3. 安全地存儲包含密鑰的 JSON 文件。

通過服務帳戶進行授權時,您有兩種選擇來向您的應用程序提供憑據。您可以設置GOOGLE_APPLICATION_CREDENTIALS環境變量,也可以在代碼中將路徑顯式傳遞給服務帳戶密鑰。第一個選項更安全,強烈推薦。

設置環境變量:

將環境變量GOOGLE_APPLICATION_CREDENTIALS設置為包含您的服務帳號密鑰的 JSON 文件的文件路徑。此變量僅適用於您當前的 shell 會話,因此如果您打開一個新會話,請再次設置該變量。

Linux 或 macOS

export GOOGLE_APPLICATION_CREDENTIALS="/home/user/Downloads/service-account-file.json"

視窗

使用 PowerShell:

$env:GOOGLE_APPLICATION_CREDENTIALS="C:\Users\username\Downloads\service-account-file.json"

完成上述步驟後,應用程序默認憑據 (ADC) 能夠隱式確定您的憑據,允許您在測試或在非 Google 環境中運行時使用服務帳戶憑據。

將您的 Firebase 憑據與您的首選語言的Google 身份驗證庫一起使用,以檢索短期 OAuth 2.0 訪問令牌:

節點.js

 function getAccessToken() {
  return admin.credential.applicationDefault().getAccessToken()
      .then(accessToken => {
        return accessToken.access_token;
      })
      .catch(err => {
        console.error('Unable to get access token');
        console.error(err);
      });
}

在此示例中,Google API 客戶端庫使用 JSON Web 令牌或 JWT 對請求進行身份驗證。有關更多信息,請參閱JSON Web 令牌

Python

def _get_access_token():
  """Retrieve a valid access token that can be used to authorize requests.

  :return: Access token.
  """
  credentials = ServiceAccountCredentials.from_json_keyfile_name(
      'service-account.json', SCOPES)
  access_token_info = credentials.get_access_token()
  return access_token_info.access_token

爪哇

private static String getAccessToken() throws IOException {
  GoogleCredentials googleCredentials = GoogleCredentials
          .fromStream(new FileInputStream("service-account.json"))
          .createScoped(Arrays.asList(SCOPES));
  googleCredentials.refreshAccessToken();
  return googleCredentials.getAccessToken().getTokenValue();
}

訪問令牌過期後,會自動調用令牌刷新方法來檢索更新的訪問令牌。

要授權訪問遠程配置,請請求範圍https://www.googleapis.com/auth/firebase.remoteconfig

修改遠程配置模板

使用遠程配置模板時,請記住它們是版本化的,並且每個版本從創建時間到您用更新替換它的時間都有一個有限的生命週期:90 天,總共限制 300 個存儲版本。有關詳細信息,請參閱模板和版本控制

獲取當前的遠程配置模板

您可以使用後端 API 以 JSON 格式獲取遠程配置模板的當前活動版本。

在 A/B 測試實驗中專門作為變體創建的參數和參數值不包含在導出的模板中。

使用以下命令:

捲曲

curl --compressed -D headers -H "Authorization: Bearer token" -X GET https://firebaseremoteconfig.googleapis.com/v1/projects/my-project-id/remoteConfig -o filename

此命令將 JSON 有效負載輸出到一個文件,並將標頭(包括 Etag)輸出到一個單獨的文件。

原始 HTTP 請求

Host: firebaseremoteconfig.googleapis.com

GET /v1/projects/my-project-id/remoteConfig HTTP/1.1
Authorization: Bearer token
Accept-Encoding: gzip

此 API 調用返回以下 JSON,以及一個包含用於後續請求的ETag的單獨標頭。

驗證遠程配置模板

或者,您可以在發布更新之前對其進行驗證。通過將 URL 參數?validate_only=true附加到您的發布請求來驗證模板更新。在響應中,狀態代碼 200 和帶有後綴-0的更新 etag 表示您的更新已成功驗證。任何非 200 響應都表示 JSON 數據包含您必須在發布前更正的錯誤。

更新遠程配置模板

檢索模板並使用所需更新修改 JSON 內容後,您可以發布它。按照本節中的說明發布模板會將整個現有配置模板替換為更新的文件,並且為新的活動模板分配比它替換的模板大一號的版本號。

如有必要,您可以使用 REST API回滾到以前的版本。為了降低更新中出錯的風險,您可以在發布前進行驗證

遠程配置個性化和條件包含在下載的模板中,因此在嘗試發佈到其他項目時,請務必注意以下限制:

  • 個性化不能從一個項目導入到另一個項目。

    例如,如果您在項目中啟用了個性化並下載和編輯模板,則可以將其發佈到同一個項目,但不能將其發佈到不同的項目,除非您從模板中刪除個性化。

  • 條件可以從一個項目導入到另一個項目,但請注意,任何特定的條件值(如應用 ID 或受眾)在發布之前都應該存在於目標項目中。

    例如,如果您有一個 Remote Config 參數,該參數使用指定iOS平台值的條件,則可以將模板發佈到另一個項目,因為任何項目的平台值都是相同的。但是,如果它包含依賴於特定應用 ID 或目標項目中不存在的用戶受眾的條件,則驗證將失敗。

  • 如果您計劃發布的模板包含依賴 Google Analytics 的條件,則必須在目標項目中啟用 Analytics。

捲曲

curl --compressed -H "Content-Type: application/json; UTF8" -H "If-Match: last-returned-etag" -H "Authorization: Bearer token" -X PUT https://firebaseremoteconfig.googleapis.com/v1/projects/my-project-id/remoteConfig -d @filename

對於此curl命令,您可以使用“@”字符後跟文件名來指定內容。

原始 HTTP 請求

Host: firebaseremoteconfig.googleapis.com
PUT /v1/projects/my-project-id/remoteConfig HTTP/1.1
Content-Length: size
Content-Type: application/json; UTF8
Authorization: Bearer token
If-Match: expected ETag
Accept-Encoding: gzip
JSON_HERE

因為這是一個寫請求,所以該命令修改了ETag ,並在下一個PUT命令的響應標頭中提供了更新的 ETag。

修改遠程配置條件

您可以以編程方式修改遠程配置條件和條件值。使用 REST API,您必須在發布模板之前直接編輯模板以修改條件。

{
  "conditions": [{
    "name": "android_english",
    "expression": "device.os == 'android' && device.country in ['us', 'uk']",
    "tagColor": "BLUE"
  }, {
    "name": "tenPercent",
    "expression": "percent <= 10",
    "tagColor": "BROWN"
  }],
  "parameters": {
    "welcome_message": {
      "defaultValue": {
        "value": "Welcome to this sample app"
      },
      "conditionalValues": {
        "tenPercent": {
          "value": "Welcome to this new sample app"
        }
      },
      "description": "The sample app's welcome message"
    },
    "welcome_message_caps": {
      "defaultValue": {
        "value": "false"
      },
      "conditionalValues": {
        "android_english": {
          "value": "true"
        }
      },
      "description": "Whether the welcome message should be displayed in all capital letters."
    }
  }
}

上面的修改首先定義了一組條件,然後為每個參數定義了默認值和基於條件的參數( conditional values )值。它還為每個元素添加了可選描述;像代碼註釋一樣,這些是供開發人員使用的,不會顯示在應用程序中。還提供了一個ETag用於版本控制。

遠程配置後端 API 提供了幾個條件和比較運算符,您可以使用它們來更改應用程序的行為和外觀。要了解有關條件和這些條件支持的運算符的更多信息,請參閱條件表達式參考

HTTP 錯誤代碼

狀態碼意義
200成功更新
400發生驗證錯誤。例如,包含超過允許數量的鍵(2000)的請求將返回 400(錯誤請求)以及錯誤消息Param count too large 。此外,此 HTTPS 狀態代碼可能會在以下兩種情況下出現:
  • 發生版本不匹配錯誤,因為自您上次檢索 ETag 值以來已更新了一組值和條件。要解決此問題,您應該使用GET命令獲取新模板和 ETag 值,更新模板,然後使用該模板和新 ETag 值提交。
  • 在未指定If-Match標頭的情況下發出了PUT命令(更新遠程配置模板請求)。
401發生授權錯誤(未提供訪問令牌或 Firebase Remote Config REST API 未添加到您在 Cloud Developer Console 中的項目中)
403發生身份驗證錯誤(提供了錯誤的訪問令牌)
500發生了內部錯誤。如果發生此錯誤,請提交 Firebase 支持票證

狀態碼 200 表示遠程配置模板(項目的參數、值和條件)已更新,現在可供使用此項目的應用程序使用。其他狀態碼表示之前存在的遠程配置模板仍然有效。

向模板提交更新後,請轉到 Firebase 控制台以驗證您的更改是否按預期顯示。這很關鍵,因為條件的順序會影響它們的評估方式(評估為true的第一個條件生效)。

ETag 使用和強制更新

遠程配置 REST API 使用實體標籤 (ETag) 來防止競爭條件和資源的重疊更新。要了解有關 ETag 的更多信息,請參閱ETag - HTTP

對於 REST API,Google 建議您緩存最新的GET命令提供的 ETag,並在發出PUT命令時在If-Match請求標頭中使用該 ETag 值。如果您的PUT命令導致 HTTPS 狀態代碼 409,您應該發出一個新的GET命令來獲取一個新的 ETag 和模板以與您的下一個PUT命令一起使用。

您可以通過強制按如下方式更新遠程配置模板來規避 ETag 及其提供的保護: If-Match: *但是,不建議使用此方法,因為它有可能導致遠程配置更新丟失如果多個客戶端正在更新遠程配置模板,則為模板。這種衝突可能發生在使用 API 的多個客戶端,或者來自 API 客戶端和 Firebase 控制台用戶的更新衝突。

有關管理遠程配置模板版本的指南,請參閱遠程配置模板和版本控制