Join us for Firebase Summit on November 10, 2021. Tune in to learn how Firebase can help you accelerate app development, release with confidence, and scale with ease. Register

Modificar o Configuração remota de maneira programática

Neste documento, descrevemos como ler e modificar de maneira programática o conjunto de parâmetros e condições formatados em JSON conhecidos como modelo do Configuração remota. Isso permite que você faça alterações no modelo do back-end que o app cliente pode buscar usando a biblioteca de cliente.

Usando a API REST do Configuração remota ou os SDKs Admin descritos neste guia, é possível ignorar o gerenciamento do modelo no Console do Firebase para integrar diretamente as alterações do Configuração remota nos seus próprios processos. Por exemplo, com as APIs de back-end do Configuração remota, é possível fazer o seguinte:

  • Agendar atualizações do Configuração remota: ao usar chamadas de API com um cron job, é possível alterar os valores do Configuração remota regularmente.
  • Importar valores de configuração em lotes: realize esta ação para fazer a transação de modo eficiente do seu próprio sistema para o Configuração remota do Firebase.
  • Usar o Configuração remota com o Cloud Functions para Firebase: você altera valores no seu app com base em eventos que acontecem no lado do servidor. Por exemplo, você pode usar o Configuração remota para promover um novo recurso no seu app e desativar imediatamente a promoção quando perceber que um número suficiente de pessoas já interagiu com a nova função.

As seções a seguir deste guia descrevem as operações que você consegue realizar com as APIs de back-end do Configuração remota. Para revisar alguns códigos que realizam essas tarefas por meio da API REST, consulte um destes apps de exemplo (em inglês):

Modificar o Configuração remota usando o SDK Admin do Firebase

O SDK Admin é um conjunto de bibliotecas de servidor que permite interagir com o Firebase em ambientes com privilégios. Além de realizar atualizações no Configuração remota, o SDK Admin permite a geração e a verificação de tokens de autenticação do Firebase, leitura e gravação no Realtime Database, entre outros. Para saber mais sobre os pré-requisitos e a configuração do SDK Admin, consulte Adicionar o SDK Admin do Firebase ao servidor.

Em um fluxo típico do Configuração remota, é possível ver o modelo atual, modificar alguns dos parâmetros ou grupos e condições de parâmetros, validar o modelo e publicá-lo. Antes de fazer essas chamadas de API, você precisa autorizar solicitações do SDK.

Inicializar o SDK e autorizar solicitações de API

Quando você inicializa o SDK Admin sem parâmetros, o SDK usa o Google Application Default Credentials e lê as opções da variável de ambiente FIREBASE_CONFIG. Caso o conteúdo da variável FIREBASE_CONFIG comece com uma {, ele será analisado como um objeto JSON. Caso contrário, a string será tratada pelo SDK como o nome de um arquivo JSON que contém as opções.

Exemplo:

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

Ver o modelo atual do Configuração remota

Ao trabalhar com modelos do Configuração remota, lembre-se de que cada versão tem uma vida útil limitada, que vai desde a criação até a substituição por meio de uma atualização: 90 dias, com um limite total de 300 versões armazenadas. Consulte Modelos e controle de versões para mais informações.

É possível usar as APIs de back-end para ver a versão ativa atual do modelo do Configuração remota no formato JSON. Para ver o modelo:

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

Modificar parâmetros do Configuração remota

É possível modificar e adicionar parâmetros e grupos de parâmetros do Configuração remota. Por exemplo, para um grupo de parâmetros atual chamado "new_menu", é possível adicionar um parâmetro para controlar a exibição de informações sazonais:

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

A API permite que você crie novos parâmetros e grupos de parâmetros ou modifique valores padrão, valores condicionais e descrições. Em todos os casos, você precisa publicar explicitamente o modelo depois de fazer as modificações.

Modificar condições do Configuração remota

É possível modificar e adicionar de forma programática condições e valores condicionais do Configuração remota. Por exemplo, para adicionar uma nova condição:

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

Em todos os casos, você precisa publicar explicitamente o modelo depois de fazer as modificações.

As APIs de back-end do Configuração remota oferecem várias condições e operadores de comparação que podem ser usados para alterar o comportamento e a aparência do seu aplicativo. Para saber mais sobre as condições e os operadores compatíveis com elas, consulte a referência de expressão condicional.

Validar o modelo do Configuração remota

Se preferir, valide as atualizações antes de publicá-las, conforme mostrado a seguir:

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

Esse processo de validação verifica se há erros, como chaves duplicadas de parâmetros e condições, nomes de condições inválidas ou condições não existentes ou etags incorretas. Por exemplo, uma solicitação que contém mais do que o número permitido de chaves (2.000) retornaria a mensagem de erro Param count too large.

Publicar o modelo do Configuração remota

Depois de recuperar um modelo e revisá-lo com as atualizações desejadas, será possível publicá-lo. A publicação de um modelo, conforme descrito nesta seção, substitui todo o modelo de configuração atual pelo arquivo atualizado. Além disso, o novo modelo ativo recebe uma versão que é um número maior do que o modelo substituído.

Se necessário, use a API REST para reverter para a versão anterior. Para reduzir o risco de erros em uma atualização, valide antes de publicar.

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

Modificar o Configuração remota usando a API REST

Nesta seção, descrevemos os principais recursos da API REST do Configuração remota em https://firebaseremoteconfig.googleapis.com. Para detalhes completos, consulte a referência da API.

Receber um token de acesso para autenticar e autorizar solicitações de API

Os projetos do Firebase oferecem suporte a contas de serviço do Google, que podem ser usadas para chamar APIs do servidor do Firebase a partir do seu servidor de aplicativos ou de um ambiente confiável. Se você estiver desenvolvendo código ou implantando o aplicativo localmente, é possível usar credenciais recebidas por meio dessa conta de serviço para autorizar solicitações do servidor.

Para autenticar uma conta de serviço e autorizá-la para acessar os serviços do Firebase, gere um arquivo de chave privada no formato JSON.

Para gerar um arquivo de chave privada da conta de serviço, siga estas etapas:

  1. No Console do Firebase, abra Configurações > Contas de serviço.

  2. Clique em Gerar nova chave privada e selecione Gerar chave para confirmar.

  3. Armazene com segurança o arquivo JSON que contém a chave.

Ao autorizar por meio de uma conta de serviço, existem duas opções para fornecer as credenciais ao seu aplicativo. Defina a variável de ambiente GOOGLE_APPLICATION_CREDENTIALS ou transmita explicitamente o caminho para a chave da conta de serviço no código. A primeira opção é mais segura e é altamente recomendável.

Para definir a variável de ambiente:

Defina a variável de ambiente GOOGLE_APPLICATION_CREDENTIALS como o caminho do arquivo JSON que contém a chave da conta de serviço. Essa variável só se aplica à sessão de shell atual. Dessa maneira, se você abrir uma nova sessão, defina a variável novamente.

Linux ou macOS

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

Windows

Com o PowerShell:

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

Depois de concluir as etapas acima, o Application Default Credentials (ADC) pode determinar implicitamente suas credenciais, permitindo que você use as credenciais da conta de serviço ao testar ou executar em ambientes que não são do Google.

Use as credenciais do Firebase com a Biblioteca do Google Auth para sua linguagem preferida e recupere um token de acesso do OAuth 2.0 de curta duração:

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

Neste exemplo, a biblioteca de cliente da API do Google autentica a solicitação com um token JSON da Web ou JWT. Para mais informações, consulte tokens JSON da web.

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

private static String getAccessToken() throws IOException {
  GoogleCredentials googleCredentials = GoogleCredentials
          .fromStream(new FileInputStream("service-account.json"))
          .createScoped(Arrays.asList(SCOPES));
  googleCredentials.refreshAccessToken();
  return googleCredentials.getAccessToken().getTokenValue();
}

O método de atualização de token é chamado automaticamente para recuperar um token atualizado após o de acesso expirar.

Para autorizar o acesso ao Configuração remota, solicite o escopo https://www.googleapis.com/auth/firebase.remoteconfig.

Modificar o modelo do Configuração remota

Ao trabalhar com modelos do Configuração remota, lembre-se de que cada versão tem uma vida útil limitada, que vai desde a criação até a substituição por meio de uma atualização: 90 dias, com um limite total de 300 versões armazenadas. Consulte Modelos e controle de versões para mais informações.

Ver o modelo atual do Configuração remota

É possível usar as APIs de back-end para ver a versão ativa atual do modelo do Configuração remota no formato JSON. Use os seguintes 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 exporta o payload do JSON para um arquivo e os cabeçalhos (incluindo a ETag) para um arquivo separado.

Solicitação HTTP bruta

Host: firebaseremoteconfig.googleapis.com

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

Essa chamada de API retorna o JSON a seguir com um cabeçalho separado que inclui uma ETag usada para a solicitação subsequente.

Validar o modelo do Configuração remota

Se preferir, valide suas atualizações antes de publicá-las. Para validar as atualizações do modelo, inclua o parâmetro de URL ?validate_only=true na solicitação de publicação. Na resposta, um código de status 200 e uma ETag atualizada com o sufixo -0 significa que sua atualização foi validada com êxito. Qualquer resposta que não tenha o código 200 indica que os dados JSON contêm erros que precisam ser corrigidos antes da publicação.

Atualizar o modelo do Configuração remota

Depois de recuperar um modelo e revisar o conteúdo do JSON com as atualizações desejadas, ele estará pronto para publicação. A publicação de um modelo, conforme descrito nesta seção, substitui todo o modelo de configuração atual pelo arquivo atualizado. Além disso, o novo modelo ativo recebe uma versão que é um número maior do que o modelo substituído.

Se necessário, use a API REST para reverter para a versão anterior. Para reduzir o risco de erros em uma atualização, valide antes de publicar.

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 este comando curl, especifique o conteúdo usando o caractere "@" seguido pelo nome do arquivo.

Solicitação HTTP bruta

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

Como esta é uma solicitação de gravação, a ETag é modificada por esse comando e uma ETag atualizada é fornecida nos cabeçalhos da resposta ao próximo comando PUT.

Modificar condições do Configuração remota

É possível modificar de maneira programática as condições e os valores condicionais do Configuração remota. Na API REST, antes de publicar o modelo, é necessário editá-lo diretamente para modificar as condições.

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

As modificações acima definem primeiro um conjunto de condições e, em seguida, os valores padrão e de parâmetros baseados em condições (valores condicionais) de cada parâmetro. Além disso, adicionam uma descrição opcional para cada elemento. Assim como os comentários de código, eles são para uso do desenvolvedor e não são exibidos no aplicativo. Uma ETag também é fornecida para fins de controle de versão.

As APIs de back-end do Configuração remota oferecem várias condições e operadores de comparação que podem ser usados para alterar o comportamento e a aparência do seu aplicativo. Para saber mais sobre as condições e os operadores compatíveis com elas, consulte a referência de expressão condicional.

Códigos de erro HTTP

Código de status Significado
200 Atualizado com sucesso.
400 Ocorreu um erro de validação. Por exemplo, uma solicitação que contém mais do que o número de chaves permitido (2.000) retorna o código 400 (Solicitação inválida) com a mensagem de erro Param count too large. Além disso, código de status HTTPS pode ocorrer em duas situações:
  • Ocorreu um erro de incompatibilidade de versão porque o conjunto de valores e condições foi atualizado após a última vez em que você recuperou um valor de ETag. Para resolver esse problema, você deve usar um comando GET para receber um novo modelo e valor de ETag e, depois, atualize e envie o modelo.
  • Um comando PUT (solicitação de modelo atualizado do Configuração remota) foi usado sem a especificação de um cabeçalho If-Match.
401 Ocorreu um erro de autorização. Isso significa que nenhum token de acesso foi fornecido ou a Firebase Remote Config REST API não foi adicionada ao seu projeto no Console para desenvolvedores do Cloud.
403 Ocorreu um erro de autenticação. O token de acesso fornecido está incorreto.
500 Ocorreu um erro interno. Se esse erro ocorrer, envie um tíquete de suporte para o Firebase.

Um código de status 200 indica que o modelo do Configuração remota (parâmetros, valores e condições do projeto) foi atualizado e agora está disponível para apps que usam esse projeto. Outros códigos de status indicam que o modelo do Configuração remota de antes ainda está em vigor.

Depois de enviar atualizações para seu modelo, acesse o Console do Firebase e verifique se as alterações estão sendo exibidas conforme o esperado. Esta ação é fundamental, já que a ordem das condições afeta o modo como elas são definidas. A primeira condição que tiver uma definição true entrará em vigor.

Uso de ETag e atualizações forçadas

A Remote Config REST API usa uma tag de entidade (ETag) para evitar que ocorram condições de corrida e sobreposições das atualizações nos recursos. Para saber mais sobre ETags, acesse ETag – HTTP (em inglês).

Para a API REST, o Google recomenda armazenar em cache a ETag fornecida pelo comando GET mais recente e usar esse valor de ETag no cabeçalho da solicitação If-Match ao emitir comandos PUT. Se o comando PUT resultar em um código de status HTTPS 409, emita um novo comando GET para receber uma nova ETag e um novo modelo a ser usado com seu próximo comando PUT.

É possível contornar a ETag e a proteção que ela fornece. Para isso, basta forçar a atualização do modelo do Configuração remota da seguinte forma: If-Match: * No entanto, essa abordagem não é recomendada porque você correrá o risco de perder as atualizações do seu modelo caso vários clientes estejam atualizando o modelo do Configuração remota. Esse tipo de conflito poderá ocorrer se vários clientes estiverem usando a API ou se houver atualizações conflitantes de clientes de APIs e usuários do Console do Firebase.

Para ver orientações sobre o gerenciamento de versões de modelos do Configuração remota, consulte Modelos e controle de versões do Configuração remota.