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 SDK s 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 valuesin 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
.
py