|---|---|
| **Select template type:** | [Client templates](https://firebase.google.com/docs/remote-config/templates/client.md.txt) [Server templates](https://firebase.google.com/docs/remote-config/templates/server.md.txt) |

<br />

Remote Config templates are sets of JSON-formatted parameters and
conditions created for your Firebase project. Client templates serve
configurations to app instances that implement the Firebase client SDKs
for Remote Config, including Apple, Android, Web, Flutter, Unity, and
C++ apps.

You can use the Firebase console to modify and manage your client template.
Go to **DevOps \& Engagement** \> **Remote Config** to view the contents of the
template in graphical format on the
[**Parameters** page](https://console.firebase.google.com/project/_/config)
and
[**Conditions** page](https://console.firebase.google.com/project/_/config/conditions).

You can also use the
[Remote Config REST API and Admin SDK](https://firebase.google.com/docs/remote-config/automate-rc.md.txt)
or the [Firebase CLI](https://firebase.google.com/docs/remote-config/automate-rc.md.txt#use-config-cli) to
modify and manage your client template.

Here's an example of a client template file:

```json
{
  "conditions": [
    {
      "name": "ios",
      "expression": "device.os == 'ios'"
    }
  ],
  "parameters": {
    "welcome_message": {
      "defaultValue": {
        "value": "Welcome to this sample app"
      },
      "conditionalValues": {
        "ios": {
          "value": "Welcome to this sample iOS app"
        }
      }
    },
    "welcome_message_caps": {
      "defaultValue": {
        "value": "false"
      }
    },
    "header_text": {
      "defaultValue": {
        "useInAppDefault": true
      }
    }
  },
  "version": {
    "versionNumber": "28",
    "updateTime": "2020-05-14T18:39:38.994Z",
    "updateUser": {
      "email": "user@google.com"
    },
    "updateOrigin": "CONSOLE",
    "updateType": "INCREMENTAL_UPDATE"
  }
}
```

You can perform these version management tasks in the Firebase console
(navigate to **DevOps \& Engagement** \>
[**Remote Config**](https://console.firebase.google.com/project/_/config/)):

- List all stored template versions
- Retrieve a specific version
- Roll back to a specific client version
- Delete Remote Config templates from the [**Change history** page](https://console.firebase.google.com/project/_/config/history).

You can also list templates, retrieve templates, and roll back templates using
the Firebase CLI and Remote Config backend APIs.

There is a total limit of 300 lifetime stored versions per template type
(300 client templates and 300 server templates), which includes stored
version numbers for deleted templates. If you publish more than 300
template versions per template type during the lifetime of a project, the
earliest versions are deleted, maintaining a maximum of 300 versions of
that type.

Each time you update parameters, Remote Config creates a
new versioned Remote Config template and stores the previous template as
a version that you can retrieve or roll back to as needed. Version numbers
are incremented sequentially from the initial value stored by Remote Config.
All templates include a `version` field as shown, containing metadata about that
specific version.

You can delete Remote Config templates as needed in the
**DevOps \& Engagement** \> **Remote Config** \>
[**Change history** page](https://console.firebase.google.com/project/_/config/history)
of the Firebase console.

## Manage Remote Config template versions

This section describes how to manage versions of your Remote Config
template.

For more detail on how to create,
modify, and save templates programmatically, see
[Modify Remote Config programmatically](https://firebase.google.com/docs/remote-config/automate-rc.md.txt).

### List all stored versions of the Remote Config template

You can retrieve a list of
all stored versions of the Remote Config template. To do this:

### Firebase console

1. In the Firebase console, go to the
   **DevOps \& Engagement** \> **Remote Config** \>
   [**Parameters** page](https://console.firebase.google.com/project/_/config).

2. Select the "clock" icon displayed at top right.

   This opens the
   [**Change history** page](https://console.firebase.google.com/project/_/config/history)
   which lists all stored template versions in a list menu at the right.

   Details displayed for each stored version include information on whether
   the changes originated with the Firebase console, with the REST API,
   from a rollback, or whether they were incremental changes from a forced
   save of the template.

### Firebase CLI

```
firebase remoteconfig:versions:list
```

Use the `--limit` option to limit the number of versions being returned.
Pass '0' to fetch all versions.

### Node.js

```javascript
function listAllVersions() {
admin.remoteConfig().listVersions()
.then((listVersionsResult) => {
  console.log("Successfully fetched the list of versions");
  listVersionsResult.versions.forEach((version) => {
    console.log('version', JSON.stringify(version));
  });
})
.catch((error) => {
  console.log(error);
});
}
```

### Java

```java
ListVersionsPage page = FirebaseRemoteConfig.getInstance().listVersionsAsync().get();
while (page != null) {
  for (Version version : page.getValues()) {
    System.out.println("Version: " + version.getVersionNumber());
  }
  page = page.getNextPage();
}

// Iterate through all versions. This will still retrieve versions in batches.
page = FirebaseRemoteConfig.getInstance().listVersionsAsync().get();
for (Version version : page.iterateAll()) {
  System.out.println("Version: " + version.getVersionNumber());
}
```

### REST

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

The list of templates includes metadata for all stored versions, including the
time of the update, the user who made it, and how it was made. Here is an
example of a version element:

```json
{
  "versions": [{
    "version_number": "6",
    "update_time": "2022-05-12T02:38:54Z",
    "update_user": {
      "name": "Jane Smith",
      "email": "jane@developer.org",
      "imageUrl": "https://lh3.googleusercontent.com/a-/..."
    },
    "description": "One small change on the console",
    "origin": "CONSOLE",
    "update_type": "INCREMENTAL_UPDATE"
  }]
}
```

### Retrieve a specific version of the Remote Config template

You can retrieve any specific stored version of the Remote Config template.
Here's how to retrieve a stored template version:

### Firebase console

1. In the Firebase console, go to the
   **DevOps \& Engagement** \> **Remote Config** \>
   [**Change history** page](https://console.firebase.google.com/project/_/config/history).

2. By default, the page displays the current active template. To view a
   different version, select it from the details pane on the right.

3. View a detailed diff of the active template and any other stored version
   by hovering over the context menu for any non-selected version
   and selecting **Compare with selected version.**

### Firebase CLI

```
firebase remoteconfig:get -v VERSION_NUMBER
```

Optionally, you can write the output to a specified file with
`-o, FILENAME`.

### Node.js

Pass `getTemplate`
without any arguments to retrieve the latest version of the template,
or to retrieve a specific version, use `getTemplateAtVersion`.

```javascript
// Get template version: 6
admin.remoteConfig().getTemplateAtVersion('6')
.then((template) => {
console.log("Successfully fetched the template with ETag: " + template.etag);
})
.catch((error) => {
console.log(error);
});
```

### Java

```java
Template template = FirebaseRemoteConfig.getInstance().getTemplateAtVersionAsync(versionNumber).get();
// See the ETag of the fetched template.
System.out.println("Successfully fetched the template with ETag: " + template.getETag());
```

### REST

```restructuredtext
curl --compressed -D headers -H "Authorization: Bearer token" -X GET https://firebaseremoteconfig.googleapis.com/v1/projects/my-project-id/remoteConfig?version_number=6
```

The URL parameter `?version_number` is valid only for `GET` operations;
you can't use it to specify version numbers for updates. A similar get
request without the `?version_number`
parameter would retrieve the current active template.

### Roll back to a specific stored version of the Remote Config template

You can roll back to any stored version of the template. Here's how to roll back
a template:

### Firebase console

1. In the Firebase console, go to the
   **DevOps \& Engagement** \> **Remote Config** \>
   [**Change history** page](https://console.firebase.google.com/project/_/config/history).

2. Locate the option button at the top right of the page for previous
   template versions eligible for rollback.

3. Click and confirm this only if you are sure you want to roll back to that
   version and use those values *immediately* for all apps and users.

### Firebase CLI

```
firebase remoteconfig:rollback -v VERSION_NUMBER
```

### Node.js

```javascript
// Roll back to template version: 6
admin.remoteConfig().rollback('6')
  .then((template) => {
    console.log("Successfully rolled back to template version 6.");
    console.log("New ETag: " + template.etag);
  })
  .catch((error) => {
    console.log('Error trying to rollback:', e);
  })
```

### Java

```java
try {
  Template template = FirebaseRemoteConfig.getInstance().rollbackAsync(versionNumber).get();
  System.out.println("Successfully rolled back to template version: " + versionNumber);
  System.out.println("New ETag: " + template.getETag());
} catch (ExecutionException e) {
  if (e.getCause() instanceof FirebaseRemoteConfigException) {
    FirebaseRemoteConfigException rcError = (FirebaseRemoteConfigException) e.getCause();
    System.out.println("Error trying to rollback template.");
    System.out.println(rcError.getMessage());
  }
}
```

### REST

To roll back to a stored Remote Config template, issue an HTTP POST with
the custom method `:rollback` and, in the request body, the specific
version to apply. For example:

```restructuredtext
curl --compressed -D headers -H "Authorization: Bearer token" -H "Content-Type: application/json" -X POST https://firebaseremoteconfig.googleapis.com/v1/projects/my-project-id/remoteConfig:rollback -d '{"version_number": 6}'
```

The response contains the contents of the now-active stored template, with
its new version metadata.

Note that this rollback operation effectively creates
a new numbered version. For example, rolling back from version 10 to version 6
effectively creates a new copy of version 6, differing
from the original only in that its version number is 11. The original version 6
is still stored, assuming it has not reached its expiration, and version 11
becomes the active template.

### Delete a Remote Config template

You can delete Remote Config templates using the Firebase console.
Here's how to delete a template:

1. In the Firebase console, go to the
   **DevOps \& Engagement** \> **Remote Config** \>
   [**Parameters** page](https://console.firebase.google.com/project/_/config).

2. Click
   [**Change history**](https://console.firebase.google.com/project/_/config/history).

3. Toggle to the template you want to delete, click
   **More**, then
   select **Delete**.

4. When prompted to confirm the deletion, click **Delete**.

## Download and publish Remote Config templates

Download and publish Remote Config templates to integrate them into your
source control and build systems, automate config updates, and keep parameters
and values in sync across multiple projects.

You can download the currently active Remote Config template
programmatically or from the Firebase console. You can then update the
exported JSON file and publish it to the same project, or publish it to a new
or existing project.

For example, suppose you have multiple projects that represent different stages
of your software development lifecycle, like development, test, staging, and
production environments. In this case, you could promote a fully-tested
template from your staging environment to your production environment by
downloading it from your staging project and publishing it to your production
project.

You can also use this method to migrate configurations from one project to
another, or populate a new project with parameters and values from an
established project.

Parameters and parameter values created specifically as variants in an
A/B Testing experiment are not included in exported templates.

To export and import Remote Config templates:

1. [Download the current Remote Config template](https://firebase.google.com/docs/remote-config/templates/client.md.txt#download-current-template).
2. [Validate the Remote Config template](https://firebase.google.com/docs/remote-config/templates/client.md.txt#validate-template).
3. [Publish the Remote Config template](https://firebase.google.com/docs/remote-config/templates/client.md.txt#publish-template).

### Download the current Remote Config template

Use the following to download the active Remote Config template in
JSON format:

### Firebase console

1. In the Firebase console, go to the
   **DevOps \& Engagement** \> **Remote Config** \>
   [**Parameters or Conditions** page](https://console.firebase.google.com/project/_/config).

2. Open the
   **Menu**, and
   select **Download current config file**.

3. When prompted, click **Download config file** , choose the location where
   you want to save the file, then click **Save**.

### Firebase CLI

```
firebase remoteconfig:get -o filename
```

### Node.js

```javascript
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

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

### REST

```restructuredtext
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 `headers` file.

### Validate the Remote Config template

You can validate your template updates before publishing them using the
Firebase Admin SDK or the REST API. Templates are also validated when you attempt
to publish from the Firebase CLI or Firebase console.

The template 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`.

### Node.js

```javascript
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

```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());
  }
}
```

### REST

Validate template updates by appending URL parameter
`?validate_only=true` to your publish request:

<br />

```restructuredtext
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?validate_only=true -d @filename
```

<br />

If your template was successfully validated, the curl command returns the
JSON template you submitted and, in the saved `headers` file, you'll find
an HTTP/2 status 200 and an updated ETag with the suffix `-0`. If your
template wasn't validated, you'll receive the validation error in the
JSON response and your `headers` file will contain a non-200 response
(and no ETag).

### Publish the Remote Config template

After downloading a template, making any needed changes to the JSON content, and
validating it, you can publish it to a project.

Publishing a template replaces the entire existing config template with the
updated file and increments the template version by one. Because the entire
configuration is replaced, if you delete a parameter from the JSON file and
publish it, the parameter is deleted from the server and is no longer available
to clients.

After publishing, changes to parameters and values are *immediately* available
to your apps and users. If necessary, you can
[roll back to a previous version](https://firebase.google.com/docs/remote-config/templates/client.md.txt#rollback).

Use the following commands to publish your template:

### Firebase console

1. In the Firebase console, go to the
   **DevOps \& Engagement** \> **Remote Config** \>
   [**Parameters or Conditions** page](https://console.firebase.google.com/project/_/config).

2. Open the
   **Menu**,
   and select **Publish from a file**.

3. When prompted, click **Browse** , navigate to and select the
   Remote Config file you want to publish, then click **Select**.

4. Firebase validates the file. If validation succeeds, click
   **Publish** to make the configuration immediately available to your
   apps and users.

### Node.js

```javascript
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

```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

```restructuredtext
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.

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.

### Download Remote Config template defaults

Because your app might not always be connected to the internet,
you should configure client-side app default values for all Remote Config
parameters. You should also periodically synchronize your app client default
values and Remote Config backend default parameter values, because they
might change over time.

As described in the platform-specific links at the end of this section, you can
manually set these defaults in your app or you can streamline this process by
downloading files that contain *only* the key-value pairs for all parameters
and their default values in the active Remote Config template. You can then
include this file in your project and configure your app to import these values.

You can download these files in XML format for Android apps,
property list (plist) format for iOS apps, and JSON for web apps.

Periodically download Remote Config defaults before any
new app release to ensure that your app and the Remote Config backend stay
in sync.

> [!WARNING]
> **Warning:** If **(in-app default)** is enabled for Remote Config parameters, the downloaded default values are empty. When using this feature, configure default values for all parameters in the Firebase console.

Here's how to download a file that contains template defaults:

### REST

```
curl --compressed -D headers -H "Authorization: Bearer token -X GET https://firebaseremoteconfig.googleapis.com/v1/projects/my-project-id/remoteConfig:downloadDefaults?format=file_format'
```

Use `XML`, `PLIST`, or `JSON` as the `format` value, depending on which
file format you want to download.

### Firebase console

1. In the Firebase console, go to the
   **DevOps \& Engagement** \> **Remote Config** \>
   [**Parameters** page](https://console.firebase.google.com/project/_/config).

2. Open the
   **Menu**, and
   select **Download default values**.

3. When prompted, click the radio button that corresponds to the file
   format you want to download, and then click **Download file**.

For more information about importing Remote Config default values into your
app, see:

- [Set in-app default parameter values for Android](https://firebase.google.com/docs/remote-config/get-started.md.txt?&platform=android#set_in_app_default_parameter_values)

- [Set in-app default parameter values for iOS](https://firebase.google.com/docs/remote-config/get-started.md.txt?&platform=ios#set_in_app_default_parameter_values)

- [Set in-app default parameter values for Web](https://firebase.google.com/docs/remote-config/get-started.md.txt?&platform=web#set_in_app_default_parameter_values)

- [Set in-app default parameter values for Unity](https://firebase.google.com/docs/remote-config/get-started.md.txt?&platform=unity#set_in_app_default_parameter_values)

- [Set in-app default parameter values for C++](https://firebase.google.com/docs/remote-config/get-started.md.txt?&platform=cpp#set_in_app_default_parameter_values)