Modifica Remote Config de manera programática

En este documento, se describe cómo leer y modificar de manera programática el conjunto de parámetros y condiciones con formato JSON conocido como la plantilla de Remote Config. Esto te permite modificar la plantilla en el backend, de manera que la app cliente pueda recuperar esos cambios mediante la biblioteca cliente.

Con la API de REST de Remote Config o los Admin SDK que se describen en esta guía, puedes omitir la administración de la plantilla en Firebase console para integrar directamente los cambios de Remote Config en tus propios procesos. Por ejemplo, con las APIs de backend de Remote Config, podrías hacer lo siguiente:

  • Programar actualizaciones de Remote Config. Si usas llamadas a la API junto con un trabajo cron, puedes cambiar los valores de Remote Config con regularidad
  • Importar los valores de configuración por lotes para realizar una transición eficiente de tu propio sistema a Firebase Remote Config.
  • Usar Remote Config con Cloud Functions for Firebase y cambiar los valores en tu app según los eventos que ocurren en el servidor. Por ejemplo, puedes usar Remote Config para promocionar una función nueva en tu app y, luego, desactivar automáticamente esa promoción una vez que detectes que suficientes usuarios interactuaron con la función.

    Diagrama en el que se muestra el backend de Remote Config interactuando con herramientas y servidores personalizados

En las siguientes secciones de esta guía, se describen las operaciones que puedes realizar con las APIs de backend de Remote Config. Para revisar el código que realiza estas tareas a través de la API de REST, consulta una de estas apps de ejemplo:

Modifica Remote Config con el SDK de Firebase Admin

Admin SDK es un conjunto de bibliotecas de servidor que te permiten interactuar con Firebase desde entornos privilegiados. Además de realizar actualizaciones en Remote Config, Admin SDK permite generar y verificar tokens de autenticación de Firebase, leer y escribir desde Realtime Database, etcétera. Para obtener más información acerca de los requisitos previos y la configuración de Admin SDK, consulta Agrega el SDK de Firebase Admin a tu servidor.

En un flujo típico de Remote Config, puedes obtener la plantilla actual, modificar algunos de los parámetros o grupos de parámetros y condiciones, validar la plantilla y, luego, publicarla. Antes de realizar esas llamadas a la API, debes autorizar las solicitudes desde el SDK.

Inicializa el SDK y autoriza las solicitudes a la API

Cuando inicializas Admin SDK sin parámetros, el SDK usa credenciales predeterminadas de la aplicación de Google y lee las opciones de la variable de entorno FIREBASE_CONFIG. Si el contenido de la variable FIREBASE_CONFIG comienza con un {, se analizará como un objeto JSON. De lo contrario, el SDK supone que el string es el nombre de un archivo JSON que contiene las opciones.

Por ejemplo:

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);

Obtén la plantilla actual de Remote Config

Cuando trabajes con plantillas de Remote Config, ten en cuenta que tienen versiones y que cada una de ellas tiene una vida útil limitada desde el momento de su creación hasta que la reemplazas por una actualización de 90 días, con un límite total de 300 versiones almacenadas. Consulta Plantillas y control de versiones para obtener más información.

Puedes usar las APIs de backend para obtener la versión activa actual de la plantilla de Remote Config en formato JSON.

En las plantillas exportadas, no se incluyen los parámetros ni valores de parámetros creados específicamente como variantes en un experimento de A/B Testing.

Usa los siguientes comandos para obtener la plantilla:

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

Modifica los parámetros de Remote Config

Puedes modificar y agregar de manera programática los parámetros y grupos de parámetros de Remote Config. Por ejemplo, en un grupo de parámetros llamado “new_menu”, puedes agregar uno para controlar cómo se muestra la información de temporada:

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.")
        );

La API te permite crear grupos de parámetros y parámetros nuevos, o modificar valores predeterminados, condicionales y descripciones. En todos los casos, debes publicar la plantilla de forma explícita después de realizar modificaciones.

Modifica las condiciones de Remote Config

Puedes modificar y agregar de manera programática condiciones y valores condicionales de Remote Config. Por ejemplo, para agregar una condición nueva, haz lo siguiente:

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));

En todos los casos, debes publicar la plantilla de forma explícita después de realizar modificaciones.

Las APIs de backend de Remote Config proporcionan varias condiciones y operadores de comparación que puedes usar para cambiar el comportamiento y el aspecto de tu app. Si quieres obtener más información acerca de las condiciones y sus operadores compatibles, consulta la referencia de expresiones condicionales.

Valida la plantilla de Remote Config

De manera opcional, puedes validar tus actualizaciones antes de publicarlas, como se muestra a continuación:

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

En este proceso de validación, se comprueba si hay errores, como claves duplicadas para parámetros y condiciones, nombres de condiciones no válidos, condiciones inexistentes o ETags con errores de formato. Por ejemplo, una solicitud que contiene más claves que la cantidad permitida (2,000) mostraría el mensaje de error Param count too large.

Publica la plantilla de Remote Config

Luego de recuperar una plantilla y revisarla con las actualizaciones deseadas, puedes publicarla. Publicar una plantilla como se describe en esta sección reemplaza toda la plantilla de configuración existente por el archivo actualizado y se le asigna un número de versión mayor que el de la plantilla que reemplazó.

Si es necesario, puedes usar la API de REST para revertir a la versión anterior. Para mitigar el riesgo de errores en una actualización, puedes validarla antes de publicarla.

Las personalizaciones y condiciones de Remote Config se incluyen en las plantillas descargadas, por lo que es importante tener en cuenta las siguientes limitaciones cuando intentes publicar en un proyecto diferente:

  • Las personalizaciones no se pueden importar de un proyecto a otro.

    Por ejemplo, si tienes personalizaciones habilitadas en tu proyecto y descargas y editas una plantilla, puedes publicarla en el mismo proyecto, pero no en otro proyecto, a menos que borres las personalizaciones de la plantilla.

  • Las condiciones se pueden importar de un proyecto a otro, pero ten en cuenta que cualquier valor condicional específico (como IDs de app o públicos) debe existir en el proyecto de destino antes de la publicación.

    Por ejemplo, si tienes un parámetro de Remote Config que usa una condición que especifica un valor de plataforma de iOS, la plantilla se puede publicar en otro proyecto, ya que los valores de plataforma son los mismos para cualquier proyecto. Sin embargo, si contiene una condición que depende de un ID de app específico o de un público de usuarios que no existe en el proyecto de destino, la validación fallará.

  • Si la plantilla que quieres publicar contiene condiciones que dependen de Google Analytics, Analytics debe estar habilitado en el proyecto de destino.

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

Modifica Remote Config con la API de REST

En esta sección, se describen las funciones principales de la API de REST de Remote Config en https://firebaseremoteconfig.googleapis.com. Para obtener más información, consulta la referencia de la API.

Obtén un token de acceso para autenticar y autorizar solicitudes a la API

Los proyectos de Firebase son compatibles con las cuentas de servicio de Google, por lo que puedes llamar a las APIs del servidor de Firebase desde tu servidor de apps o un entorno de confianza. Si desarrollas código o implementas tu aplicación de manera local, puedes usar las credenciales obtenidas mediante la cuenta de servicio para autorizar las solicitudes del servidor.

Para autenticar una cuenta de servicio y autorizar su acceso a los servicios de Firebase, debes generar un archivo de claves privadas en formato JSON.

Sigue estos pasos a fin de generar un archivo de claves privadas para la cuenta de servicio:

  1. En la consola de Firebase, abre Configuración > Cuentas de servicio.

  2. Haz clic en Generar nueva clave privada y luego en Generar clave para confirmar.

  3. Almacena de forma segura el archivo JSON que contiene la clave.

Cuando autorices mediante una cuenta de servicio, tendrás dos opciones para proporcionar las credenciales a la aplicación. Puedes configurar la variable de entorno GOOGLE_APPLICATION_CREDENTIALS o pasar la ruta a la clave de la cuenta de servicio en el código de forma explícita. Recomendamos enfáticamente que uses la primera opción, ya que es más segura.

Para configurar la variable de entorno, haz lo siguiente:

Configura la variable de entorno GOOGLE_APPLICATION_CREDENTIALS con la ruta del archivo JSON que contiene la clave de tu cuenta de servicio. Esta variable solo se aplica a la sesión actual de Cloud Shell. Por lo tanto, si abres una sesión nueva, deberás volver a configurar la variable.

Linux o macOS

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

Windows

Con PowerShell:

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

Cuando completes los pasos anteriores, el servicio de credenciales predeterminadas de la aplicación (ADC) puede determinar de forma implícita tus credenciales, lo que te permite usar credenciales de cuentas de servicio cuando realizas pruebas o ejecutas aplicaciones en entornos de terceros.

Para recuperar el token de acceso de OAuth 2.0 de corta duración, usa las credenciales de Firebase y la biblioteca de Google Auth en tu lenguaje preferido, como se muestra a continuación:

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

En este ejemplo, la biblioteca cliente de la API de Google autentica la solicitud con un token web JSON o JWT. Para obtener más información, consulta la sección sobre los tokens web 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();
}

Cuando venza el token de acceso, se llamará al método de actualización automáticamente para obtener un token actualizado.

Para autorizar el acceso a Remote Config, solicita el permiso https://www.googleapis.com/auth/firebase.remoteconfig.

Modifica la plantilla de Remote Config

Cuando trabajes con plantillas de Remote Config, ten en cuenta que tienen versiones y que cada una de ellas tiene una vida útil limitada desde el momento de su creación hasta que la reemplazas por una actualización de 90 días, con un límite total de 300 versiones almacenadas. Consulta Plantillas y control de versiones para obtener más información.

Obtén la plantilla actual de Remote Config

Puedes usar las APIs de backend para obtener la versión activa actual de la plantilla de Remote Config en formato JSON.

En las plantillas exportadas, no se incluyen los parámetros ni valores de parámetros creados específicamente como variantes en un experimento de A/B Testing.

Usa los siguientes comandos:

cURL

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

Este comando envía la carga útil JSON a un archivo y los encabezados (incluida la Etag) a un archivo independiente.

Solicitud HTTP sin procesar

Host: firebaseremoteconfig.googleapis.com

GET /v1/projects/my-project-id/remoteConfig HTTP/1.1
Authorization: Bearer token
Accept-Encoding: gzip

Esta llamada a la API muestra el siguiente JSON, junto con un encabezado independiente que incluye una ETag que debes usar para la solicitud posterior.

Valida la plantilla de Remote Config

Además, puedes validar tus actualizaciones antes de publicarlas. Para ello, adjunta a tu solicitud de publicación el parámetro de URL ?validate_only=true. Si la respuesta tiene el código de estado 200 y la ETag aparece actualizada con el sufijo -0, la actualización se validó correctamente. Cualquier respuesta que no sea 200 indica que los datos de JSON contienen errores que debes corregir antes de publicar.

Actualiza la plantilla de Remote Config

Luego de recuperar una plantilla y revisar el contenido JSON con las actualizaciones deseadas, puedes publicarla. Publicar una plantilla como se describe en esta sección reemplaza toda la plantilla de configuración existente por el archivo actualizado y se le asigna un número de versión mayor que el de la plantilla que reemplazó.

Si es necesario, puedes usar la API de REST para revertir a la versión anterior. Para mitigar el riesgo de errores en una actualización, puedes validarla antes de publicarla.

Las personalizaciones y condiciones de Remote Config se incluyen en las plantillas descargadas, por lo que es importante tener en cuenta las siguientes limitaciones cuando intentes publicar en un proyecto diferente:

  • Las personalizaciones no se pueden importar de un proyecto a otro.

    Por ejemplo, si tienes personalizaciones habilitadas en tu proyecto y descargas y editas una plantilla, puedes publicarla en el mismo proyecto, pero no en otro proyecto, a menos que borres las personalizaciones de la plantilla.

  • Las condiciones se pueden importar de un proyecto a otro, pero ten en cuenta que cualquier valor condicional específico (como IDs de app o públicos) debe existir en el proyecto de destino antes de la publicación.

    Por ejemplo, si tienes un parámetro de Remote Config que usa una condición que especifica un valor de plataforma de iOS, la plantilla se puede publicar en otro proyecto, ya que los valores de plataforma son los mismos para cualquier proyecto. Sin embargo, si contiene una condición que depende de un ID de app específico o de un público de usuarios que no existe en el proyecto de destino, la validación fallará.

  • Si la plantilla que quieres publicar contiene condiciones que dependen de Google Analytics, Analytics debe estar habilitado en el proyecto de destino.

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

Para el comando curl, puedes especificar el contenido mediante el carácter “@” seguido del nombre del archivo.

Solicitud HTTP sin procesar

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

Debido a que se trata de una solicitud de escritura, este comando modifica la ETag y se proporciona una actualizada en los encabezados de respuesta del comando PUT siguiente.

Modifica las condiciones de Remote Config

Puedes modificar de manera programática condiciones y valores condicionales de Remote Config. Con la API de REST, debes editar la plantilla directamente para modificar las condiciones antes de publicarla.

{
  "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."
    }
  }
}

Las modificaciones anteriores definen primero un conjunto de condiciones y, luego, los valores predeterminados y los parámetros basados en condiciones (valores condicionales) para cada parámetro. También agrega una descripción opcional para cada elemento. Al igual que los comentarios de código, estas son para el uso de los desarrolladores y no se muestran en la app. Además, se proporciona una ETag para fines de control de versión.

Las APIs de backend de Remote Config proporcionan varias condiciones y operadores de comparación que puedes usar para cambiar el comportamiento y el aspecto de tu app. Si quieres obtener más información acerca de las condiciones y sus operadores compatibles, consulta la referencia de expresiones condicionales.

Códigos de error de HTTP

Código de estado Significado
200 Se actualizó correctamente
400 Ocurrió un error de validación. Por ejemplo, una solicitud que contiene más claves que la cantidad permitida (2,000) muestra el código 400 (Solicitud incorrecta) con el mensaje de error Param count too large. Además, este código de estado HTTPS puede aparecer en estas dos situaciones:
  • Se produjo un error de coincidencia de versión debido a que el conjunto de valores y condiciones se actualizó desde que recuperaste el valor de una ETag por última vez. Para resolver esto, debes usar un comando GET para obtener una plantilla nueva y el valor de la ETag, actualizar la plantilla y, a continuación, enviarla con el valor de la ETag nueva.
  • Se aplicó un comando PUT (una solicitud de actualización de la plantilla de Remote Config) sin especificar un encabezado If-Match.
401 Se produjo un error de autorización (no se proporcionó ningún token de acceso o no se agregó la API de REST de Firebase Remote Config a tu proyecto en Cloud Developer Console).
403 Se produjo un error de autenticación (se proporcionó un token de acceso incorrecto).
500 Se produjo un error interno. En este caso, envía un ticket de asistencia de Firebase.

Un código de estado 200 significa que la plantilla de Remote Config (parámetros, valores y condiciones del proyecto) se actualizó y ahora está disponible para las apps que usan este proyecto. Otros códigos de estado indican que la plantilla de Remote Config que existía anteriormente sigue en vigencia.

Después de enviar actualizaciones a tu plantilla, ve a Firebase console para verificar que los cambios aparezcan como esperabas. Esto es fundamental, ya que el orden de las condiciones afecta la manera en que se evalúan (se aplica la primera condición evaluada como true).

Uso de la ETag y actualizaciones forzadas

La API de REST de Remote Config usa una etiqueta de entidad (ETag) para evitar condiciones de carrera y la superposición de actualizaciones en los recursos. Para obtener más información sobre ETags, consulta ETag - HTTP.

Para la API de REST, Google recomienda almacenar en caché la ETag que proporcionó el comando GET más reciente y usar el valor de esa ETag en el encabezado de la solicitud If-Match cuando emitas comandos PUT. Si el comando PUT genera un código de estado HTTPS 409, debes emitir un comando GET nuevo para obtener una ETag y una plantilla nuevas para usar con el siguiente comando PUT.

Para eludir la ETag y la protección que proporciona, puedes forzar la plantilla de Remote Config para que se actualice de la siguiente manera: If-Match: * Sin embargo, no se recomienda este enfoque porque corre el riesgo de provocar la pérdida de actualizaciones de tu plantilla de Remote Config si varios clientes actualizan esa plantilla de Remote Config. Este tipo de conflicto podría ocurrir si hay varios clientes usando la API o si varios clientes de la API y usuarios de Firebase console envían actualizaciones incompatibles.

Si necesitas orientación para administrar las versiones de plantillas de Remote Config, consulta Plantillas y control de versiones de Remote Config.