透過程式輔助方式修改遠端設定

本文說明如何以程式輔助方式讀取及修改一組 JSON 格式的參數和條件,也就是所謂的Remote Config範本。這樣一來,您就能在後端變更範本,而用戶端應用程式可使用用戶端程式庫擷取這些範本。

使用本指南所述的 Remote Config REST APIAdmin SDK,您可以略過在 Firebase 控制台中管理範本的步驟,直接將 Remote Config 變更整合至自己的程序。舉例來說,您可以使用 Remote Config 後端 API 執行下列操作:

  • 安排Remote Config更新時間。搭配使用 API 呼叫和 cron 工作,即可定期變更 Remote Config 值。
  • 批次匯入設定值,以便從自有系統有效率地轉換至 Firebase Remote Config
  • 搭配 Cloud Functions for Firebase 使用 Remote Config,根據伺服器端發生的事件變更應用程式中的值。舉例來說,您可以利用 Remote Config 宣傳應用程式中的新功能,並在偵測到有足夠的使用者與新功能互動後,自動關閉宣傳活動。

    圖表:遠端設定後端與自訂工具和伺服器互動

本指南的以下各節說明如何使用 Remote Config 後端 API 執行操作。如要查看透過 REST API 執行這些工作的程式碼,請參閱下列其中一個範例應用程式:

使用 Firebase Admin SDK 修改遠端設定

Admin SDK 是一組伺服器程式庫,可讓您從具備權限的環境與 Firebase 互動。除了更新 Remote ConfigAdmin SDK 還能產生及驗證 Firebase 驗證權杖、從 Realtime Database 讀取及寫入資料等。如要進一步瞭解Admin SDK必要條件和設定,請參閱「在伺服器中新增 Firebase Admin SDK」。

在一般的 Remote Config 流程中,您可能會取得目前的範本、修改部分參數或參數群組和條件、驗證範本,然後發布範本。發出這些 API 呼叫前,您必須授權 SDK 的要求。

初始化 SDK 並授權 API 要求

初始化 Admin SDK 時,如果沒有任何參數,SDK 會使用 Google 應用程式預設憑證,並從 FIREBASE_CONFIG 環境變數讀取選項。如果 FIREBASE_CONFIG 變數的內容以 { 開頭,系統會將其剖析為 JSON 物件。否則 SDK 會假設該字串是含有選項的 JSON 檔案名稱。

例如:

Node.js

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

Java

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

取得目前的遠端設定範本

使用 Remote Config 範本時,請注意範本有版本控制,且每個版本都有生命週期限制,從建立時間到您以更新版本取代為止,生命週期為 90 天,最多可儲存 300 個版本。詳情請參閱「範本和版本管理」。

您可以使用後端 API,以 JSON 格式取得 Remote Config 範本的目前有效版本。

A/B Testing 實驗中專門建立為變體的參數和參數值,不會匯出至範本。

如要取得範本,請按照下列步驟操作:

Node.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);
      });
}

Java

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

修改遠端設定參數

您可以透過程式輔助方式修改及新增 Remote Config 參數和參數群組。舉例來說,您可以將參數新增至名為「new_menu」的現有參數群組,藉此控制季節性資訊的顯示方式:

Node.js

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

Java

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

您可以使用 API 建立新參數和參數群組,或修改預設值、條件值和說明。無論如何,修改範本後都必須明確發布。

修改遠端設定條件

您可以透過程式輔助方式修改及新增 Remote Config 條件和條件值。舉例來說,如要新增條件,請按照下列步驟操作:

Node.js

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

Java

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

無論如何,修改範本後都必須明確發布。

Remote Config 後端 API 提供多種條件和比較運算子,可用於變更應用程式的行為和外觀。如要進一步瞭解條件和這些條件支援的運算子,請參閱條件運算式參考資料

驗證遠端設定範本

(選用) 您可以在發布更新前進行驗證,如下所示:

Node.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);
      });
}

Java

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 復原至先前的版本。為降低更新發生錯誤的風險,建議您先驗證再發布

Remote Config下載的範本會包含個人化設定和條件,因此嘗試發布至其他專案時,請務必留意下列限制:

  • 個人化設定無法從一個專案匯入另一個專案。

    舉例來說,如果您在專案中啟用個人化功能,並下載及編輯範本,可以將範本發布至同一個專案,但除非刪除範本中的個人化設定,否則無法發布至其他專案。

  • 您可以將條件從一個專案匯入另一個專案,但請注意,發布前,目標專案中必須存在任何特定條件值 (例如應用程式 ID 或目標對象)。

    舉例來說,如果您有使用條件的 Remote Config 參數,且該條件指定平台值為 iOS,則範本可以發布至其他專案,因為任何專案的平台值都相同。不過,如果條件依據的特定應用程式 ID 或使用者目標對象不存在於目標專案中,驗證就會失敗。

  • 如果您打算發布的範本含有依賴 Google Analytics 的條件,則必須在目標專案中啟用 Analytics

Node.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);
      });
}

Java

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 修改遠端設定

本節說明 Remote Config REST API (位於 https://firebaseremoteconfig.googleapis.com) 的主要功能。如需完整詳細資料,請參閱 API 參考資料

取得存取權杖,驗證及授權 API 要求

Firebase 專案支援 Google服務帳戶,您可以使用這些帳戶從應用程式伺服器或信任的環境呼叫 Firebase 伺服器 API。如果您在本機開發程式碼,或將應用程式部署到內部部署環境,則可使用透過這個服務帳戶取得的憑證,授權伺服器要求。

如要驗證服務帳戶並授權存取 Firebase 服務,您必須以 JSON 格式產生私密金鑰檔案。

如要為服務帳戶產生私密金鑰檔案,請按照下列步驟操作:

  1. Firebase 控制台中,開啟「設定」>「服務帳戶」

  2. 按一下「產生新的私密金鑰」,然後按一下「產生金鑰」確認。

  3. 妥善儲存內含金鑰的 JSON 檔案。

透過服務帳戶授權時,您可以選擇兩種方式,將憑證提供給應用程式。您可以設定 GOOGLE_APPLICATION_CREDENTIALS 環境變數,也可以在程式碼中明確傳送服務帳戶金鑰的路徑。第一個選項較安全,強烈建議使用。

如要設定環境變數,請按照下列指示操作:

將環境變數 GOOGLE_APPLICATION_CREDENTIALS 設為包含服務帳戶金鑰的 JSON 檔案路徑。這項變數僅適用於您目前的殼層工作階段,因此如果您開啟了新的工作階段,就必須重新設定變數。

Linux 或 macOS

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

Windows

使用 PowerShell:

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

完成上述步驟後,應用程式預設憑證 (ADC) 就能以隱含方式判斷您的憑證,讓您在非 Google 環境中測試或執行時,使用服務帳戶憑證。

使用 Firebase 憑證和偏好語言的 Google 驗證程式庫,擷取短期有效的 OAuth 2.0 存取權杖:

node.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 Token (JWT) 驗證要求。詳情請參閱 JSON 網頁符記

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

Java

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

存取權杖到期後,系統會自動呼叫權杖更新方法,以擷取更新後的存取權杖。

如要授權存取 Remote Config,請要求範圍 https://www.googleapis.com/auth/firebase.remoteconfig

修改遠端設定範本

使用 Remote Config 範本時,請注意範本有版本控制,且每個版本都有生命週期限制,從建立時間到您以更新版本取代為止,生命週期為 90 天,最多可儲存 300 個版本。詳情請參閱「範本和版本管理」。

取得目前的遠端設定範本

您可以使用後端 API,以 JSON 格式取得 Remote Config 範本的目前有效版本。

A/B Testing 實驗中專門建立為變體的參數和參數值,不會匯出至範本。

請使用下列指令:

cURL

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 的個別標頭,您可將 ETag 用於後續要求。

驗證遠端設定範本

你也可以先驗證更新內容,再發布。 在發布要求中附加網址參數 ?validate_only=true,驗證範本更新。在回應中,狀態碼 200 和更新後的 ETag (後方加上 -0) 表示更新已通過驗證。如果回應不是 200,表示 JSON 資料含有錯誤,您必須先修正錯誤才能發布。

更新遠端設定範本

擷取範本並根據所需更新修訂 JSON 內容後,即可發布範本。如本節所述發布範本,會以更新後的檔案取代整個現有設定範本,且新有效範本的版本號碼會比取代的範本大一號。

如有需要,您可以使用 REST API 復原至先前的版本。為降低更新發生錯誤的風險,建議您先驗證再發布

Remote Config下載的範本會包含個人化設定和條件,因此嘗試發布至其他專案時,請務必留意下列限制:

  • 個人化設定無法從一個專案匯入另一個專案。

    舉例來說,如果您在專案中啟用個人化功能,並下載及編輯範本,可以將範本發布至同一個專案,但除非刪除範本中的個人化設定,否則無法發布至其他專案。

  • 您可以將條件從一個專案匯入另一個專案,但請注意,發布前,目標專案中必須存在任何特定條件值 (例如應用程式 ID 或目標對象)。

    舉例來說,如果您有使用條件的 Remote Config 參數,且該條件指定平台值為 iOS,則範本可以發布至其他專案,因為任何專案的平台值都相同。不過,如果條件依據的特定應用程式 ID 或使用者目標對象不存在於目標專案中,驗證就會失敗。

  • 如果您打算發布的範本含有依賴 Google Analytics 的條件,則必須在目標專案中啟用 Analytics

cURL

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。

修改遠端設定條件

您可以透過程式輔助方式修改 Remote Config 條件和條件值。使用 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."
    }
  }
}

上述修改內容會先定義一組條件,然後為每個參數定義預設值和以條件為準的參數 (條件值) 值。此外,這項工具還會為每個元素新增選填說明;這些說明與程式碼註解類似,僅供開發人員使用,不會顯示在應用程式中。為方便進行版本控管,這項工具也會提供 ETag

Remote Config 後端 API 提供多種條件和比較運算子,可用於變更應用程式的行為和外觀。如要進一步瞭解條件和這些條件支援的運算子,請參閱條件運算式參考資料

HTTP 錯誤代碼

狀態碼 意義
200 更新成功
400 發生驗證錯誤。舉例來說,如果要求包含超過允許的鍵數 (2000 個),系統會傳回 400 (Bad Request) 錯誤,並顯示錯誤訊息 Param count too large。此外,在下列兩種情況下,也可能出現這個 HTTPS 狀態碼:
  • 由於值和條件集在您上次擷取 ETag 值後已更新,因此發生版本不符錯誤。如要解決這個問題,請使用 GET 指令取得新範本和 ETag 值,更新範本,然後使用該範本和新的 ETag 值提交。
  • 執行 PUT 指令 (更新 Remote Config 範本要求) 時,未指定 If-Match 標頭。
401 發生授權錯誤 (未提供存取權杖,或尚未在 Cloud 開發人員控制台中將 Firebase Remote Config REST API 新增至專案)
403 發生驗證錯誤 (提供的存取權杖有誤)
500 發生內部錯誤,如果發生這個錯誤,請 提交 Firebase 支援票證

狀態碼 200 表示 Remote Config 範本 (專案的參數、值和條件) 已更新,現在可供使用這個專案的應用程式使用。其他狀態碼表示先前存在的 Remote Config 範本仍有效。

提交範本更新後,請前往 Firebase 控制台,確認變更是否如預期顯示。這點非常重要,因為條件的順序會影響評估方式 (系統會套用第一個評估結果為 true 的條件)。

ETag 用法和強制更新

Remote Config REST API 會使用實體標記 (ETag) 來避免競爭狀況,以及資源更新重疊。如要進一步瞭解 ETag,請參閱「ETag - HTTP」。

如果是 REST API,Google 建議您快取最新 GET 指令提供的 ETag,並在發出 PUT 指令時,於 If-Match 要求標頭中使用該 ETag 值。如果 PUT 指令傳回 HTTPS 狀態碼 409,請發出新的 GET 指令,取得新的 ETag 和範本,以便用於下一個 PUT 指令。

您可以強制更新 Remote Config 範本,藉此規避 ETag 及其提供的保護措施,方法如下:If-Match: * 不過,我們不建議採用這種做法,因為如果多個用戶端更新 Remote Config 範本,可能會導致 Remote Config 範本更新內容遺失。如果多個用戶端使用 API,或 API 用戶端和Firebase控制台使用者更新的內容有衝突,就可能發生這類衝突。

如要瞭解如何管理 Remote Config 範本版本,請參閱「Remote Config 範本和版本管理」。