Migrar de HTTP legado para HTTP v1

Os aplicativos que usam a API HTTP legada do FCM devem considerar a migração para a API HTTP v1 usando as instruções deste guia. A API HTTP v1 tem as seguintes vantagens em relação à API legada:

  • Melhor segurança por meio de tokens de acesso: a API HTTP v1 usa tokens de acesso de curta duração, de acordo com o modelo de segurança OAuth2. Se um token de acesso se tornar público, ele só poderá ser usado de maneira mal-intencionada cerca de uma hora ou menos antes de expirar. Os tokens de atualização não são transmitidos com a mesma frequência que as chaves de segurança usadas na API legada. Dessa forma, é muito menos provável que eles sejam capturados.

  • Personalização mais eficiente de mensagens em plataformas: para o corpo da mensagem, a API HTTP v1 tem chaves comuns que vão para todas as instâncias de destino, além de chaves específicas da plataforma que permitem personalizar a mensagem entre as plataformas. Com isso, você pode criar "substituições" que enviam cargas um pouco diferentes para outras plataformas de clientes em uma única mensagem.

  • Mais extensível e moderna para novas versões da plataforma do cliente: a API HTTP v1 aceita todas as opções de mensagens disponíveis no iOS, Android e na Web. Como cada plataforma tem seu próprio bloco definido no payload do JSON, o FCM pode estender a API para novas versões e plataformas, conforme necessário.

Atualizar o terminal do servidor

O URL do ponto de extremidade da API HTTP v1 é diferente do endpoint legado nos seguintes aspectos:

  • É versionado com /v1 no caminho.
  • O caminho contém o código do projeto do Firebase para seu aplicativo, no formato /projects/myproject-ID/ . Esse código está disponível na guia Configurações gerais do projeto do Console do Firebase.
  • Ele especifica explicitamente o método send como :send.

Para atualizar o endpoint do servidor para HTTP v1, adicione esses elementos ao endpoint no cabeçalho das suas solicitações de envio.

Antes

POST https://fcm.googleapis.com/fcm/send

Depois

POST https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send

Atualizar autorização de solicitações de envio

No lugar da string de chave do servidor usada nas solicitações legadas, as solicitações de envio da HTTP v1 exigem um token de acesso do OAuth 2.0. Se você estiver usando o SDK Admin para enviar mensagens, a biblioteca manipulará o token para você. Se você estiver usando o protocolo bruto, consiga o token conforme descrito nesta seção e adicione-o ao cabeçalho como Authorization: Bearer <valid Oauth 2.0 token>.

Antes

Authorization: key=AIzaSyZ-1u...0GBYzPu7Udno5aA

Depois

Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA

Dependendo dos detalhes do seu ambiente de servidor, use uma combinação destas estratégias para autorizar as solicitações do servidor para os serviços do Firebase:

  • Application Default Credentials (ADC) do Google
  • Um arquivo JSON da conta de serviço
  • Um token de acesso OAuth 2.0 de curta duração derivado de uma conta de serviço

Se seu aplicativo estiver sendo executado no Compute Engine, no Kubernetes Engine, no App Engine ou no Cloud Functions (incluindo Cloud Functions para Firebase), use o Application Default Credentials (ADC). O ADC usa sua conta de serviço padrão existente para receber credenciais para autorizar solicitações, além de permitir testes locais flexíveis por meio da variável de ambiente GOOGLE_APPLICATION_CREDENTIALS. Para receber a automação mais completa do fluxo de autorização, use o ADC junto com as bibliotecas de servidor do SDK Admin.

Se seu aplicativo estiver sendo executado em um ambiente de servidor que não seja do Google, você precisará fazer o download de um arquivo JSON da conta de serviço do seu projeto do Firebase. Contanto que você tenha acesso a um sistema de arquivos que contenha o arquivo de chave privada, você poderá usar a variável de ambiente GOOGLE_APPLICATION_CREDENTIALS para autorizar solicitações com essas credenciais recebidas manualmente. Se você não tiver acesso a esse arquivo, deverá referenciar o arquivo da conta de serviço no seu código. Tenha muito cuidado ao fazer isso, porque há risco de expor suas credenciais.

Fornecer credenciais usando o ADC

O Application Default Credentials (ADC) do Google verifica suas credenciais na seguinte ordem:

  1. O ADC verifica se a variável de ambiente GOOGLE_APPLICATION_CREDENTIALS está configurada. Caso esteja, o arquivo da conta de serviço apontado pela variável será usado.

  2. Se a variável não estiver configurada, o ADC usará a conta de serviço padrão fornecida pelo Compute Engine, Kubernetes Engine, App Engine e Cloud Functions para aplicativos executados nesses serviços.

  3. Se o ADC não puder usar nenhuma das credenciais acima, o sistema emitirá um erro.

O seguinte exemplo de código do SDK Admin ilustra essa estratégia. O exemplo não especifica explicitamente as credenciais do aplicativo. No entanto, o ADC consegue encontrar as credenciais, desde que a variável de ambiente esteja configurada ou o aplicativo esteja em execução no Compute Engine, Kubernetes Engine, App Engine ou Cloud Functions.

Node.js

admin.initializeApp({
  credential: admin.credential.applicationDefault(),
});

Java

FirebaseOptions options = new FirebaseOptions.Builder()
    .setCredentials(GoogleCredentials.getApplicationDefault())
    .setDatabaseUrl("https://<DATABASE_NAME>.firebaseio.com/")
    .build();

FirebaseApp.initializeApp(options);

Python

default_app = firebase_admin.initialize_app()

Go

app, err := firebase.NewApp(context.Background(), nil)
if err != nil {
	log.Fatalf("error initializing app: %v\n", err)
}

C#

FirebaseApp.Create(new AppOptions()
{
    Credential = GoogleCredential.GetApplicationDefault(),
});

Fornecer credenciais manualmente

Os projetos do Firebase oferecem suporte a contas de serviço do Google, que você pode usar 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 seu aplicativo localmente ou em uma nuvem que não seja do Google, em que não há suporte para o Application Default Credentials (ADC), é 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. Você precisará desse arquivo JSON para autorizar as solicitações do servidor manualmente.

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.

Usar credenciais para produzir tokens de acesso

Use suas credenciais do Firebase junto com a Biblioteca de cliente da API do Google para sua linguagem preferida e recupere um token de acesso do OAuth 2.0 de curta duração, fazendo referência ao arquivo JSON da chave privada, conforme mostrado:

node.js

 function getAccessToken() {
  return new Promise(function(resolve, reject) {
    var key = require('./service-account.json');
    var jwtClient = new google.auth.JWT(
      key.client_email,
      null,
      key.private_key,
      SCOPES,
      null
    );
    jwtClient.authorize(function(err, tokens) {
      if (err) {
        reject(err);
        return;
      }
      resolve(tokens.access_token);
    });
  });
}

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 {
  GoogleCredential googleCredential = GoogleCredential
      .fromStream(new FileInputStream("service-account.json"))
      .createScoped(Arrays.asList(SCOPES));
  googleCredential.refreshToken();
  return googleCredential.getAccessToken();
}

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

Para autorizar o acesso ao FCM, solicite o escopo https://www.googleapis.com/auth/firebase.messaging.

Para adicionar o token de acesso a um cabeçalho de solicitação HTTP:

Adicione o token como o valor do cabeçalho Authorization no formato Authorization: Bearer <access_token>:

node.js

headers: {
  'Authorization': 'Bearer ' + accessToken
}

Python

headers = {
  'Authorization': 'Bearer ' + _get_access_token(),
  'Content-Type': 'application/json; UTF-8',
}

Java

URL url = new URL(BASE_URL + FCM_SEND_ENDPOINT);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestProperty("Authorization", "Bearer " + getAccessToken());
httpURLConnection.setRequestProperty("Content-Type", "application/json; UTF-8");
return httpURLConnection;

Atualizar a carga útil de solicitações de envio

A HTTP v1 do FCM apresenta uma mudança significativa na estruturação do payload da mensagem do JSON. Primeiramente, essas alterações garantem que as mensagens sejam processadas corretamente quando recebidas em diferentes plataformas de clientes. Além disso, as alterações oferecem flexibilidade adicional para personalizar ou "substituir" campos de mensagens por plataforma.

Além de analisar os exemplos nesta seção, consulte o artigo Como personalizar uma mensagem entre plataformas e veja a referência da API para conhecer melhor a HTTP v1.

Exemplo: mensagem de notificação simples

Veja uma comparação de um payload de notificação muito simples, contendo apenas title , body e campos de data, demonstrando as diferenças fundamentais em payloads legado e HTTP v1.

Antes

{
  "to": "/topics/news",
  "notification": {
    "title": "Breaking News",
    "body": "New news story available."
  },
  "data": {
    "story_id": "story_12345"
  }
}

Depois

{
  "message": {
    "topic": "news",
    "notification": {
      "title": "Breaking News",
      "body": "New news story available."
    },
    "data": {
      "story_id": "story_12345"
    }
  }
}

Exemplo: segmentação de várias plataformas

Para ativar a segmentação de várias plataformas, a API legada realizou substituições no back-end. Por outro lado, a HTTP v1 fornece blocos de chaves específicos da plataforma que tornam as diferenças entre as plataformas explícitas e visíveis para o desenvolvedor. Com isso, você pode segmentar várias plataformas sempre com uma única solicitação, conforme demonstrado no exemplo a seguir.

Antes

// Android
{
  "to": "/topics/news",
  "notification": {
    "title": "Breaking News",
    "body": "New news story available.",
    "click_action": "TOP_STORY_ACTIVITY"
  },
  "data": {
    "story_id": "story_12345"
  }
}
// iOS
{
  "to": "/topics/news",
  "notification": {
    "title": "Breaking News",
    "body": "New news story available.",
    "click_action": "HANDLE_BREAKING_NEWS"
  },
  "data": {
    "story_id": "story_12345"
  }
}

Depois

{
  "message": {
    "topic": "news",
    "notification": {
      "title": "Breaking News",
      "body": "New news story available."
    },
    "data": {
      "story_id": "story_12345"
    }
    "android": {
      "notification": {
        "click_action": "TOP_STORY_ACTIVITY"
      }
    },
    "aps": {
      "payload": {
        "aps": {
          "category" : "NEW_MESSAGE_CATEGORY"
        }
      }
    }
  }
}

Exemplo: personalização com substituições de plataforma

Além de simplificar a segmentação de várias plataformas de mensagens, a API HTTP v1 fornece flexibilidade para personalizar mensagens por plataforma.

Antes

// Android
{
  "to": "/topics/news",
  "notification": {
    "title": "Breaking News",
    "body": "Check out the Top Story.",
    "click_action": "TOP_STORY_ACTIVITY"
  },
  "data": {
    "story_id": "story_12345"
  }
}
// iOS
{
  "to": "/topics/news",
  "notification": {
    "title": "Breaking News",
    "body": "New news story available.",
    "click_action": "HANDLE_BREAKING_NEWS"
  },
  "data": {
    "story_id": "story_12345"
  }
}

Depois

{
  "message": {
    "topic": "news",
    "notification": {
      "title": "Breaking News",
      "body": "New news story available."
    },
    "data": {
      "story_id": "story_12345"
    },
    "android": {
      "notification": {
        "click_action": "TOP_STORY_ACTIVITY",
        "body": "Check out the Top Story"
      }
    },
    "apns": {
      "payload": {
        "aps": {
          "category" : "NEW_MESSAGE_CATEGORY"
        }
      }
    }
  }
}

Para mais exemplos e informações sobre a API FCM HTTP v1, consulte o Blog do Firebase.

Enviar comentários sobre…

Precisa de ajuda? Acesse nossa página de suporte.