This document describes how you can programmatically read and modify the set of JSON-formatted parameters and conditions known as the Remote Config template. This allows you to make template changes on the backend that the client app can fetch using the client library.
Using the Remote Config REST API or the Admin SDKs described in this guide, you can bypass managing the template in the Firebase console to directly integrate Remote Config changes into your own processes. For example, with Remote Config backend APIs, you could:
- Scheduling Remote Config updates. By using API calls in conjunction with a cron job, you can change Remote Config values on a regular schedule.
- Batch import config values in order to transition efficiently from your own proprietary system to Firebase Remote Config.
Use Remote Config with Cloud Functions for Firebase, changing values in your app based on events that happen server-side. For example, you can use Remote Config to promote a new feature in your app, and then turn off that promotion automatically once you detect enough people have interacted with the new feature.
The following sections of this guide describe operations you can do with the Remote Config backend APIs. To review some code that performs these tasks via the REST API, see one of these sample apps:
- Firebase Remote Config REST API Java Quickstart
- Firebase Remote Config REST API Node.js Quickstart
- Firebase Remote Config REST API Python Quickstart
Modify Remote Config using the Firebase Admin SDK
The Admin SDK is a set of server libraries that let you interact with Firebase from privileged environments. In addition to performing updates to Remote Config, the Admin SDK enables generation and verification of Firebase auth tokens, reading and writing from Realtime Database, and so on. To learn more about Admin SDK prerequisites and setup, see Add the Firebase Admin SDK to your server.
In a typical Remote Config flow, you might get the current template, modify some of the parameters or parameter groups and conditions, validate the template, and then publish it. Before making those API calls, you must authorize requests from the SDK.
Initialize the SDK and authorize API requests
When you initialize the Admin SDK with no parameters, the SDK uses
Google Application Default Credentials
and reads options from the FIREBASE_CONFIG
environment variable.
If the content of the FIREBASE_CONFIG
variable begins with a {
it will be
parsed as a JSON object. Otherwise the SDK assumes that the string is
the name of a JSON file containing the options.
For example:
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);
Get the current Remote Config Template
When working with Remote Config templates, keep in mind that they are versioned, and that each version has a limited lifetime from its time of creation to the time you replace it with an update: 90 days, with a total limit of 300 stored versions. See Templates and Versioning for more information.
You can use the backend APIs to get the current active version of the Remote Config template in JSON format.
Parameters and parameter values created specifically as variants in an A/B Testing experiment are not included in exported templates.
To get the template:
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());
Modify Remote Config parameters
You can programmatically modify and add Remote Config parameters and parameter groups. For example, to an existing parameter group named "new_menu" you could add a parameter to control the display of seasonal information:
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.") );
The API allows you to create new parameters and parameter groups, or modify default values, conditional values, and descriptions. In all cases, you must explicitly publish the template after making modifications.
Modify Remote Config conditions
You can programmatically modify and add Remote Config conditions and conditional values. For example, to add a new condition:
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));
In all cases, you must explicitly publish the template after making modifications.
The Remote Config backend APIs provide several conditions and comparison operators that you can use to change the behavior and appearance of your app. To learn more about conditions and the operators supported for these conditions, see the conditional expression reference.
Validate the Remote Config template
Optionally, you can validate your updates before publishing them, as shown:
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()); } }
This validation process
checks for errors such as duplicate keys for parameters and conditions,
invalid condition names or nonexistent conditions, or misformatted etags.
For example, a request containing more than the allowed number of
keys—2000—would return the error message, Param count too large
.
Publish the Remote Config template
Having retrieved a template and revised it with your desired updates, you can then publish it. Publishing a template as described in this section replaces the entire existing config template with the updated file, and the new active template is assigned a version number one number greater than the template it replaced.
If necessary, you can use the REST API to roll back to the previous version. To mitigate the risk of errors in an update, you can validate before publishing.
Remote Config personalizations and conditions are included in downloaded templates, so it's important to be aware of the following limitations when attempting to publish to a different project:
Personalizations cannot be imported from project to project.
For example, if you have personalizations enabled in your project and download and edit a template, you can publish it to the same project, but you can't publish it to a different project unless you delete the personalizations from the template.
Conditions can be imported from project to project, but note that any specific conditional values (like app IDs or audiences), should exist in the target project before publishing.
For example, if you have a Remote Config parameter that uses a condition that specifies a platform value of
iOS
, the template can be published to another project, because platform values are the same for any project. However, if it contains a condition that relies on a specific app ID or user audience that doesn't exist in the target project, validation will fail.If the template you plan to publish contains conditions that rely on Google Analytics, Analytics must be enabled in the target project.
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()); } }
Modify Remote Config using the REST API
This section describes the main capabilities of the
Remote Config REST API at https://firebaseremoteconfig.googleapis.com
.
For full detail, see the API reference.
Get an access token to authenticate and authorize API requests
Firebase projects support Google service accounts, which you can use to call Firebase server APIs from your app server or trusted environment. If you're developing code locally or deploying your application on-premises, you can use credentials obtained via this service account to authorize server requests.
To authenticate a service account and authorize it to access Firebase services, you must generate a private key file in JSON format.
To generate a private key file for your service account:
In the Firebase console, open Settings > Service Accounts.
Click Generate New Private Key, then confirm by clicking Generate Key.
Securely store the JSON file containing the key.
When authorizing via a service account, you have two choices for providing the credentials to your application. You can either set the GOOGLE_APPLICATION_CREDENTIALS environment variable, or you can explicitly pass the path to the service account key in code. The first option is more secure and is strongly recommended.
To set the environment variable:
Set the environment variable GOOGLE_APPLICATION_CREDENTIALS to the file path of the JSON file that contains your service account key. This variable only applies to your current shell session, so if you open a new session, set the variable again.
Linux or macOS
export GOOGLE_APPLICATION_CREDENTIALS="/home/user/Downloads/service-account-file.json"
Windows
With PowerShell:
$env:GOOGLE_APPLICATION_CREDENTIALS="C:\Users\username\Downloads\service-account-file.json"
After you've completed the above steps, Application Default Credentials (ADC) is able to implicitly determine your credentials, allowing you to use service account credentials when testing or running in non-Google environments.
Use your Firebase credentials together with the Google Auth Library for your preferred language to retrieve a short-lived OAuth 2.0 access token:
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);
});
}
In this example, the Google API client library authenticates the request with a JSON web token, or JWT. For more information, see JSON web tokens.
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();
}
After your access token expires, the token refresh method is called automatically to retrieve an updated access token.
To authorize access to Remote Config, request the scope
https://www.googleapis.com/auth/firebase.remoteconfig
.
Modify the Remote Config template
When working with Remote Config templates, keep in mind that they are versioned, and that each version has a limited lifetime from its time of creation to the time you replace it with an update: 90 days, with a total limit of 300 stored versions. See Templates and Versioning for more information.
Get the current Remote Config Template
You can use the backend APIs to get the current active version of the Remote Config template in JSON format.
Parameters and parameter values created specifically as variants in an A/B Testing experiment are not included in exported templates.
Use the following commands:
cURL
curl --compressed -D headers -H "Authorization: Bearer token" -X GET https://firebaseremoteconfig.googleapis.com/v1/projects/my-project-id/remoteConfig -o filename
This command outputs the JSON payload to one file, and the headers (including the Etag) to a separate file.
Raw HTTP request
Host: firebaseremoteconfig.googleapis.com GET /v1/projects/my-project-id/remoteConfig HTTP/1.1 Authorization: Bearer token Accept-Encoding: gzip
This API call returns the following JSON, along with a separate header which includes an ETag that you use for the subsequent request.
Validate the Remote Config template
Optionally, you can validate your updates before publishing them.
Validate template updates by appending
to your publish request the URL parameter ?validate_only=true
.
In the response, a status code 200 and an updated etag with the suffix -0
means that your update was successfully validated. Any non-200 response
indicates that the JSON data contains errors that you must correct before
publishing.
Update the Remote Config template
Having retrieved a template and revised the JSON content with your desired updates, you can then publish it. Publishing a template as described in this section replaces the entire existing config template with the updated file, and the new active template is assigned a version number one number greater than the template it replaced.
If necessary, you can use the REST API to roll back to the previous version. To mitigate the risk of errors in an update, you can validate before publishing.
Remote Config personalizations and conditions are included in downloaded templates, so it's important to be aware of the following limitations when attempting to publish to a different project:
Personalizations cannot be imported from project to project.
For example, if you have personalizations enabled in your project and download and edit a template, you can publish it to the same project, but you can't publish it to a different project unless you delete the personalizations from the template.
Conditions can be imported from project to project, but note that any specific conditional values (like app IDs or audiences), should exist in the target project before publishing.
For example, if you have a Remote Config parameter that uses a condition that specifies a platform value of
iOS
, the template can be published to another project, because platform values are the same for any project. However, if it contains a condition that relies on a specific app ID or user audience that doesn't exist in the target project, validation will fail.If the template you plan to publish contains conditions that rely on Google Analytics, Analytics must be enabled in the target project.
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
For this curl
command, you can specify the content by using the "@" character,
followed by the filename.
Raw HTTP request
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
Because this is a write request, the ETag
is modified by this command and an updated ETag is provided in the
response headers of the next PUT
command.
Modify Remote Config conditions
You can programmatically modify Remote Config conditions and conditional values. With the REST API, you must edit the template directly to modify conditions before publishing the template.
{ "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." } } }
The modifications above first define a set of conditions, and then defines default values and condition-based parameter (conditional values) values for each parameter. It also adds an optional description for each element; like code comments, these are for developer use and are not displayed in the app. An ETag is also provided for version control purposes.
The Remote Config backend APIs provide several conditions and comparison operators that you can use to change the behavior and appearance of your app. To learn more about conditions and the operators supported for these conditions, see the conditional expression reference.
HTTP Error codes
Status Code | Meaning |
---|---|
200 | Successfully Updated |
400 | A validation error occurred. For example, a request containing more than the
allowed number of keys—2000—would return 400 (Bad Request) with
the error message, Param count too large .
Also, this HTTPS Status Code can occur in these two situations:
|
401 | An authorization error occurred (no access token was provided or the Firebase Remote Config REST API has not been added to your project in the Cloud Developer Console) |
403 | An authentication error occurred (the wrong access token was provided) |
500 | An internal error occurred. If this error occurs, file a Firebase support ticket |
A status code of 200 means that the Remote Config template (parameters, values and conditions for the project) has been updated and is now available to apps that use this project. Other status codes indicate that the Remote Config template that existed previously is still in effect.
After you submit updates to your template, go to the Firebase console to
verify that your changes appear as expected. This is critical because the
ordering of conditions affects how they are evaluated (the first condition that
evaluates true
takes effect).
ETag usage and forced updates
The Remote Config REST API uses an entity tag (ETag) to prevent race conditions and overlapping updates to resources. To learn more about ETags, see ETag - HTTP.
For the REST API, Google recommends that you cache
the ETag provided by the most recent GET
command, and use that ETag value
in the If-Match
request header when issuing PUT
commands. If your PUT
command results in an HTTPS Status Code 409, you should issue a fresh GET
command to acquire a new ETag and template to use with your next PUT
command.
You can circumvent the ETag, and the protection from that it provides, by
forcing the Remote Config template to be updated as follows: If-Match: *
However, this approach is not recommended because it risks causing the loss of
updates to your Remote Config template if multiple clients are updating the
Remote Config template. This kind of conflict could occur with multiple
clients using the API, or with conflicting updates from API clients and
Firebase console users.
For guidance on managing Remote Config template versions, see Remote Config templates and versioning.