> [!WARNING]
>
> **Preview** : Using Remote Config in server environments is a feature
> that's in Preview, which means that it isn't subject to any SLA or
> deprecation policy and could change in backwards-incompatible ways.
>
>
> As you use server-side Remote Config, we encourage you to
> [share your feedback with us](https://firebase.google.com/docs/remote-config/survey).

Firebase Remote Config supports server-side configuration using the Firebase
Admin SDKs for Node.js (v12.1.0+), Python (v6.7.0+), Java (v9.7.0+), and Go
(v4.17.0+).

This capability lets you dynamically manage the behavior and configuration of
server-side applications using Remote Config. This includes serverless
implementations like [Cloud Functions for Firebase](https://firebase.google.com/docs/functions.md.txt) and
containerized services on
[Cloud Run](https://cloud.google.com/run).
[Video](https://www.youtube.com/watch?v=yDot7SjPnjk)

Unlike Firebase client SDKs, which fetch a client-specific configuration
*derived* from the Remote Config template, the server-side Remote Config
SDK downloads or fetches a *complete* Remote Config template from Firebase.
Your server can then evaluate the template with each incoming request and use
its own logic to serve a customized response with very low latency. You can use
[conditions](https://firebase.google.com/docs/remote-config/parameters/server.md.txt#condition-rule-types)
to control and customize responses based on random percentages and client
attributes defined in
[custom signals](https://firebase.google.com/docs/remote-config/parameters/server.md.txt#custom-signals).

With server-side Remote Config, you can:

- Define configuration parameters for applications running on or accessed through your server, allowing for use cases like remotely configuring AI model parameters and prompts and other integrations, to ensure your API keys stay secure.
- Dynamically adjust parameters in response to changes in your environment or other application changes, like updating LLM parameters and model endpoints.
- Control costs by remotely updating the APIs your server calls.
- Generate custom configurations on-the-fly for clients that access your server.
- Record which clients received a parameter value and use this in Cloud Functions for Firebase as part of an entitlement verification system.

You can deploy server-side Remote Config on Cloud Run,
Cloud Functions for Firebase, or self-hosted server environments.

## Before you begin

Follow the instructions in
[Add the Firebase Admin SDK to your server](https://firebase.google.com/docs/admin/setup.md.txt)
to create a Firebase project, set up a service account, and add the Firebase
Admin SDK to your server. Make sure you use a supported version of the Admin SDK
for your platform:

- **Node.js**: Firebase Admin Node.js SDK v12.1.0+
- **Python**: Firebase Admin Python SDK v6.7.0+
- **Java**: Firebase Admin Java SDK v9.7.0+
- **Go**: Firebase Admin Go SDK v4.17.0+

### Step 1: Initialize the Firebase Admin SDK and authorize API requests

When you initialize the Admin SDK with no parameters, the SDK uses
[Google Application Default Credentials](https://developers.google.com/identity/protocols/application-default-credentials)
and reads options from the `GOOGLE_APPLICATION_CREDENTIALS` environment
variable. Initialize the SDK and configure Remote Config for your platform:

### Node.js

Import `initializeApp` and `getRemoteConfig`, then initialize your Firebase
application instance:

```javascript
import { initializeApp } from "firebase-admin/app";
import { getRemoteConfig } from "firebase-admin/remote-config";

// Initialize Firebase
const firebaseApp = initializeApp();
```

### Python

Import `firebase_admin` (along with `asyncio` and `json` for asynchronous
template loading and JSON parsing), then initialize the application:

```python
import firebase_admin
import asyncio
import json

firebase_admin.initialize_app()
```

### Java

Initialize the Firebase Admin SDK using `FirebaseOptions` and your service
account credentials:

```java
// Initialize the Firebase Admin SDK
FirebaseOptions options = new FirebaseOptions.Builder()
    .setCredentials(GoogleCredentials.fromStream(serviceAccount))
    .build();
FirebaseApp.initializeApp(options);
```

### Go

Initialize the Firebase application and create a `RemoteConfig` client
instance:

```go
ctx := context.Background()

// Initialize Firebase
app, err := firebase.NewApp(ctx, nil)
if err != nil {
    log.Fatalln("Error initializing app:", err)
}

remoteConfig, err := app.RemoteConfig(ctx)
if err != nil {
    log.Fatalln("Error initializing remote config client:", err)
}
```

### Step 2: Identify default parameter values for your server application

Identify the variables in your app that you want to dynamically update with
Remote Config. Then, consider which variables must be set by default in your
application and what their default values should be. This ensures that your
application runs successfully even if its connection to the Remote Config
backend server is interrupted.

For example, if you are writing a server application that manages a generative
AI function, you might set a default model name, prompt preamble, and a
generative AI configuration, like the following:

| **Parameter name** | **Description** | **Type** | **Default value** |
|---|---|---|---|
| `model_name` | Model API name | String | `gemini-3.8-flash` |
| `preamble_prompt` | Prompt to prepend to the user's query | String | `I'm a developer who wants to learn about Firebase and you are a helpful assistant who knows everything there is to know about Firebase!` |
| `generation_config` | Parameters to send to the model | JSON | `{"stopSequences": ["I hope this helps"], "maxOutputTokens": 512}` |

### Step 3: Configure your server application

After you've determined the parameters you want to use with Remote Config,
configure your application to set default values, fetch the server-specific
Remote Config template, and evaluate its values.

1. Access and load the Remote Config server template.

   ### Node.js

   Initialize the server template using `initServerTemplate()` and call
   `load()` to fetch the template from the backend:

   ```javascript
   // Initialize server-side Remote Config
   const rc = getRemoteConfig(firebaseApp);
   const template = rc.initServerTemplate();

   // Load Remote Config
   await template.load();
   ```

   If you're using Node.js within
   [Cloud Functions for Firebase](https://firebase.google.com/docs/functions.md.txt),
   you can use the asynchronous `getServerTemplate()` function to initialize
   and load the template in a single step:

   ```javascript
   // Initialize server-side Remote Config
   const rc = getRemoteConfig(firebaseApp);
   const template = await rc.getServerTemplate();
   ```

   ### Python

   Initialize the server template using `init_server_template()` and call
   `load()` to fetch the template from the backend:

   ```python
   from firebase_admin import remote_config

   # Initialize server-side Remote Config
   template = remote_config.init_server_template()

   # Load the template from the backend
   asyncio.run(template.load())
   ```

   Alternatively, if you're using Python with
   [Cloud Functions for Firebase](https://firebase.google.com/docs/functions.md.txt),
   you can use the asynchronous `get_server_template()` function to
   initialize and load the template in a single step:

   ```python
   # Initialize server-side Remote Config
   template = await remote_config.get_server_template()
   ```

   ### Java

   Initialize the server-side Remote Config client using
   `FirebaseRemoteConfig.getInstance()`:

   ```java
   // Initialize server-side Remote Config client
   FirebaseRemoteConfig rc = FirebaseRemoteConfig.getInstance();
   ```

   Alternatively, if you're using Java with
   [Cloud Functions for Firebase](https://firebase.google.com/docs/functions.md.txt),
   you can use `getServerTemplate()` to initialize and load the template in a
   single step:

   ```java
   ServerTemplate template = rc.getServerTemplate();
   ```

   ### Go

   Initialize the server template using `InitServerTemplate()` and call
   `Load()` to fetch the template from the backend:

   ```go
   // Initialize server-side Remote Config
   defaultConfig := make(map[string]any)
   templateDataJSON := ""
   template, err := remoteConfig.InitServerTemplate(defaultConfig, templateDataJSON)
   if err != nil {
       log.Fatalln("Error initializing server template:", err)
   }

   // Load Remote Config
   err = template.Load(ctx)
   if err != nil {
       log.Fatalln("Error fetching server template:", err)
   }
   ```

   Another way you can initialize the template is by using the
   `GetServerTemplate` function to retrieve the required server template. You
   can convert this template to a JSON format that can be stored locally, and
   subsequently initialize this JSON template using the `InitServerTemplate`
   function.
2. To ensure that your application runs successfully even if its connection to
   the Remote Config backend server is interrupted, add default values for
   each parameter in your app.

   ### Node.js

   Add a `defaultConfig` object inside your `initServerTemplate` or
   `getServerTemplate` template function:

   ```javascript
   const template = rc.initServerTemplate({
     defaultConfig: {
       model_name: "gemini-3.8-flash",
       generation_config: '{"stopSequences": [], "maxOutputTokens": 512}',
       preamble_prompt: "I'm a developer who wants to learn about Firebase and you are a helpful assistant who knows everything there is to know about Firebase!"
     },
   });

   // Load Remote Config
   await template.load();
   ```

   ### Python

   Add a `default_config` dictionary inside your `init_server_template` or
   `get_server_template` template function:

   ```python
   template = remote_config.init_server_template({
     'default_config': {
       'model_name': "gemini-3.8-flash",
       'generation_config': '{"stopSequences": [], "maxOutputTokens": 512}',
       'preamble_prompt': "I'm a developer who wants to learn about Firebase and you are a helpful assistant who knows everything there is to know about Firebase!"
     },
   })

   # Load Remote Config
   asyncio.run(template.load())
   ```

   Another way you can initialize a template is by using the
   `get_server_template` function to retrieve the required server template.
   You can convert this template to a JSON format using the
   `template.to_json` function. This JSON template can be stored locally, and
   you can subsequently initialize this JSON template using the
   `init_server_template` function.

   ### Java

   Add a `defaultConfig` object using `KeysAndValues` inside your
   `getServerTemplate` function:

   ```java
   // Initialize default config using KeysAndValues
   KeysAndValues defaultConfig = new KeysAndValues.Builder()
                                     .put("rc_param_1", "default value 1")
                                     .put("rc_param_2", "default value 2")
                                     .build();
   ServerTemplate template = rc.getServerTemplate(defaultConfig);
   ```

   Alternatively, you can pass a default cached template while initializing
   Remote Config, which can be used even when the connection to the
   Remote Config server is interrupted:

   ```java
   String templateDataJSON = "{}"; // add your default template as JSON
   ServerTemplate template = rc.serverTemplateBuilder()
                       .defaultConfig(defaultConfig)
                       .cachedTemplate(templateDataJSON)
                       .build();
   ```

   ### Go

   Add a `defaultConfig` map inside your `InitServerTemplate` or
   `GetServerTemplate` template function:

   ```go
   // Initialize server-side Remote Config
   defaultConfig := make(map[string]any)
   defaultConfig["model_name"] = "gemini-3.8-flash"

   // Assume the type generationConfig has been defined
   defaultConfig["generation_config"] = &generationConfig{
       StopSequences:   []string{"I hope this helps"},
       MaxOutputTokens: 512,
   }

   defaultConfig["preamble_prompt"] = "I'm a developer who wants to learn about Firebase and you are a helpful assistant who knows everything there is to know about Firebase!"

   templateDataJSON := ""
   template, err := remoteConfig.InitServerTemplate(defaultConfig, templateDataJSON)
   if err != nil {
       log.Fatalln("Error initializing server template:", err)
   }

   // Load Remote Config
   err = template.Load(ctx)
   if err != nil {
       log.Fatalln("Error fetching server template:", err)
   }
   ```
3. After the template loads, evaluate the template to import parameters and
   values from the template:

   ### Node.js

   Use `template.evaluate()`:

   ```javascript
   // Add template parameters to config
   const config = template.evaluate();
   ```

   ### Python

   Use `template.evaluate()`:

   ```python
   # Add template parameters to config
   config = template.evaluate()
   ```

   ### Java

   Use `template.evaluate()`:

   ```java
   // Add template parameters to config
   ServerConfig config = template.evaluate();
   ```

   ### Go

   Use `template.Evaluate()` with an empty evaluation context when no
   conditions are applied:

   ```go
   // An empty evaluation context means no conditions are applied.
   evaluationContext := make(map[string]any)
   config, err := template.Evaluate(evaluationContext)
   if err != nil {
       log.Fatalln("Error evaluating template:", err)
   }
   ```
4. Optionally, if you set
   [conditions](https://firebase.google.com/docs/remote-config/parameters/server.md.txt#condition-rule-types)
   in your Remote Config template, define and provide the context values
   you want:

   - If using [percentage conditions](https://firebase.google.com/docs/remote-config/parameters/server.md.txt#user-in-random-percentage), add the randomization ID (`randomizationId`, `randomization_id`, or `randomizationID`) that you want to use to evaluate your conditions within the template evaluation function.
   - If using [custom signals](https://firebase.google.com/docs/remote-config/parameters/server.md.txt#custom-signals), define the attributes and their values. Custom signals are available with Firebase Admin Node.js SDK v12.5.0+, Python SDK v6.7.0+, Java SDK v9.7.0+, and Go SDK v4.17.0+.

   For example, you might set a
   [Firebase installation ID](https://firebase.google.com/docs/projects/manage-installations.md.txt#retrieve_client_identifiers)
   or user ID as the randomization ID to ensure that each user that contacts
   your server is added to the proper randomized group, `version` as a custom
   signal to target specific client versions, and `platform` as a custom signal
   to target client platforms.

   > [!NOTE]
   > **Note:** The following example is simplified. In a real-world scenario, you'd likely configure your server to create unique randomization IDs for every client. This ensures that Remote Config consistently delivers the same values to each user, based on their assigned group in percentage-based conditions.

   For more information about conditions, see
   [Condition rule types](https://firebase.google.com/docs/remote-config/parameters/server.md.txt#condition-rule-types).

   ### Node.js

   Pass an evaluation context object containing `randomizationId` and any
   custom signals to `template.evaluate()`:

   ```javascript
   // Add template parameters to `config`. Evaluates the
   // template and returns the parameter value assigned to
   // the group assigned to the {randomizationId} and version.
   const config = template.evaluate({
     randomizationId: "2ac93c28-c459-4760-963d-a3974ec26c04",
     version: "1.0",
     platform: "Android"
   });
   ```

   ### Python

   Pass a dictionary containing `randomization_id` and any custom signals to
   `template.evaluate()`:

   ```python
   # Add template parameters to `config`. Evaluates the
   # template and returns the parameter value assigned to
   # the group assigned to the {randomization_id} and version.
   config = template.evaluate({
     'randomization_id': "2ac93c28-c459-4760-963d-a3974ec26c04",
     'version': "1.0",
     'platform': "Android"
   })
   ```

   ### Java

   Create a `KeysAndValues` context containing `randomizationId` and any
   custom signals, and pass it to `template.evaluate()`:

   ```java
   // Add custom signals and randomizationId
   KeysAndValues context = new KeysAndValues.Builder()
                                   .put("custom_signal_key", "99")
                                   .put("randomizationId", "2ac93c28")
                                   .build();

   // Evaluate the template with signals
   ServerConfig config = template.evaluate(context);
   ```

   ### Go

   Pass an evaluation context map containing `randomizationID` and any custom
   signals to `template.Evaluate()`:

   ```go
   // Add template parameters to `config`. Evaluates the
   // template and returns the parameter value assigned to
   // the group assigned to the {randomizationID}, version, and platform.
   evaluationContext := make(map[string]any)
   evaluationContext["randomizationID"] = "2ac93c28-c459-4760-963d-a3974ec26c04"
   evaluationContext["version"] = "1.0"
   evaluationContext["platform"] = "Android"

   config, err := template.Evaluate(evaluationContext)
   if err != nil {
       log.Fatalln("Error evaluating template:", err)
   }
   ```

   > [!IMPORTANT]
   > **Important:** If no randomization ID or custom signal is specified when evaluating the template, the default value from the Remote Config template is returned.

5. Next, extract the parameter values you need from
   the evaluated configuration object. Use getter methods to cast values from
   Remote Config into the expected format.

   For example, if you're
   [implementing Agent Platform on your server](https://docs.cloud.google.com/gemini-enterprise-agent-platform/models/start)
   and want to change the model and model parameters, you might configure
   parameters for `model_name` and `generation_config`. Here are the supported
   getter methods and an example of how to access Remote Config values for
   each platform:

   ### Node.js

   Supported getter methods:
   - Boolean: `getBoolean`
   - Object: `getValue`
   - Number: `getNumber`
   - String: `getString`

   <br />

   ```javascript
   // Replace defaults with values from Remote Config.
   const generationConfig =
     JSON.parse(
       config.getString('generation_config'));

   const is_ai_enabled = config.getBoolean('is_ai_enabled');

   const model = config.getString('model_name');

   // Generates a prompt comprised of the Remote Config
   // parameter and prepends it to the user prompt
   const prompt = `${config.getString('preamble_prompt')} ${req.query.prompt}`;
   ```

   ### Python

   Supported getter methods:
   - Boolean: `get_bool`
   - Integer: `get_int`
   - Float: `get_float`
   - String: `get_string`
   - Value source: `get_value_source`

   <br />

   ```python
   # Replace defaults with values from Remote Config.
   generation_config = json.loads(config.get_string('generation_config'))
   is_ai_enabled = config.get_bool('is_ai_enabled')
   model = config.get_string('model_name')

   # Generates a prompt comprised of the Remote Config
   # parameter and prepends it to the user prompt.
   prompt = f"{config.get_string('preamble_prompt')}{req.args.get('prompt')}"
   ```

   ### Java

   Supported getter methods:
   - Boolean: `getBoolean`
   - String: `getString`
   - Double: `getDouble`
   - Long: `getLong`
   - Value source: `getValueSource`

   <br />

   ```java
   // Get the model name
   String modelName = config.getString("model_name");
   // Get the origin of value assigned to param
   ValueSource modelNameSource = config.getValueSource("model_name");
   ```

   The method `getValueSource` returns a `ValueSource` that indicates whether
   the parameter's value source is `STATIC`, `REMOTE`, or `DEFAULT`.

   ### Go

   Supported getter methods:
   - Boolean: `GetBoolean`
   - Integer: `GetInt`
   - Float: `GetFloat`
   - String: `GetString`
   - Value source: `GetValueSource`

   <br />

   ```go
   // Replace defaults with values from Remote Config.

   // Assume the type generationConfig has been defined
   var genConfig generationConfig
   err = json.Unmarshal([]byte(config.GetString("generation_config")), &genConfig)
   if err != nil {
       log.Fatalln("Error unmarshaling generation config:", err)
   }
   model := config.GetString("model_name")

   // Parameter created on the console
   isAIEnabled := config.GetBoolean("is_ai_enabled")

   // Generates a prompt comprised of the Remote Config
   // parameter and prepends it to the user prompt (assume it is extracted from the request body)
   userPrompt := "What is Remote Config?"
   prompt := fmt.Sprintf("%s %s", config.GetString("preamble_prompt"), userPrompt)
   ```
6. If your server is long-running, as opposed to a serverless environment,
   periodically reload the template (for example, using `setInterval` in
   Node.js or `java.util.Timer` in Java) to confirm that you're fetching the
   most up-to-date template from the Remote Config server.

### Step 4: Set server-specific parameter values in Remote Config

Next, create a server Remote Config template and configure parameters and
values to use in your app.

Here's how to create a server-specific Remote Config template:

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

2. From the **Client/Server** selector at the top of the page, select
   **Server**.

3. Define Remote Config parameters with the same names and data types as
   the parameters that you defined in your app and provide values. These values
   will override the default configuration (`defaultConfig` or
   `default_config`) you set in
   [Configure your server application](https://firebase.google.com/docs/remote-config/server.md.txt#configure-server-app)
   when you fetch and evaluate the template and assign these values to your
   variables.

4. Optionally, set conditions to persistently apply values to a random sample
   of instances or custom signals you define. For more information about
   conditions, see
   [Condition rule types](https://firebase.google.com/docs/remote-config/parameters/server.md.txt#condition-rule-types).

5. When you've finished adding parameters, click **Publish changes**.

6. Review the changes and click **Publish changes** again.

### Step 5: Deploy with Cloud Functions for Firebase or Cloud Run

If your server application is lightweight and event-driven, you should consider
deploying your code using [Cloud Functions for Firebase](https://firebase.google.com/docs/functions.md.txt). For
example, say you have an app that includes character dialogue powered by a
generative AI API (for example, Google AI or Agent Platform). In this case, you
could host your LLM-serving logic in a function that your app calls on-demand.

- To work through a solution that uses 2nd gen Cloud Functions for Firebase with
  server-side Remote Config, see
  [Use server-side Remote Config with Cloud Functions for Firebase and Agent Platform](https://firebase.google.com/docs/remote-config/solution-server.md.txt).

- To learn more about deploying your app with Cloud Functions for Firebase, see
  [Get started: write, test, and deploy your first functions](https://firebase.google.com/docs/functions/get-started.md.txt).

- Try out a sample callable function with server-side Remote Config and
  App Check at
  [Call the Agent Platform Gemini API (formerly Vertex AI) with Remote Config and App Check](https://github.com/firebase/functions-samples/tree/main/Node/call-vertex-remote-config-server).

If you're building a server-rendered web app,
[App Hosting](https://firebase.google.com/docs/app-hosting.md.txt)
has support for popular web frameworks.

Otherwise, you might consider
[Cloud Run](https://cloud.google.com/run).
To deploy your server app with Cloud Run, follow the quickstart guide
for your language:

- [Quickstart: Deploy a Node.js service to Cloud Run](https://cloud.google.com/run/docs/quickstarts/build-and-deploy/deploy-nodejs-service)
- [Quickstart: Deploy a Python service to Cloud Run](https://cloud.google.com/run/docs/quickstarts/build-and-deploy/deploy-python-service)
- [Quickstart: Deploy a Java service to Cloud Run](https://cloud.google.com/run/docs/quickstarts/build-and-deploy/deploy-java-service)
- [Quickstart: Deploy a Go service to Cloud Run](https://cloud.google.com/run/docs/quickstarts/build-and-deploy/deploy-go-service)

> [!NOTE]
> **Note:** Cloud Functions for Firebase, App Hosting, and Cloud Run require billing accounts. See [Cloud Functions for Firebase pricing](https://firebase.google.com/pricing.md.txt) and [Cloud Run pricing](https://cloud.google.com/run/pricing) for more information.

## Next steps

- Explore server-side parameters and conditions in [Parameters and conditions (server-side)](https://firebase.google.com/docs/remote-config/parameters/server.md.txt).
- Work through a complete solution: [Use server-side Remote Config with Cloud Functions for Firebase and Agent Platform](https://firebase.google.com/docs/remote-config/solution-server.md.txt).
- Learn how to [manage Remote Config template versions](https://firebase.google.com/docs/remote-config/templates/server.md.txt).