Os apps que usam as APIs legadas e descontinuadas do FCM para HTTP e XMPP precisam migrar para a API HTTP v1 o mais rápido possível. O envio de mensagens, incluindo mensagens upstream, com essas APIs foi descontinuado em 20 de junho de 2023, e a desativação começa em 22 de julho de 2024.
Saiba mais sobre os recursos específicos afetados.
Além do suporte contínuo e dos novos recursos, a API HTTP v1 tem as seguintes vantagens em relação às APIs legadas:
Melhor segurança usando tokens de acesso: a API HTTP v1 utiliza tokens de acesso de curta duração conforme o modelo de segurança OAuth2. Se um token de acesso se tornar público, ele só poderá ser usado de maneira mal-intencionada por cerca de uma hora 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 todas as 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 em várias plataformas. Com isso, você pode criar "substituições" que enviam payloads um pouco diferentes para outras plataformas de clientes em uma única mensagem.
Flexibilidade para garantir a compatibilidade com novas versões da plataforma do cliente: a API HTTP v1 tem suporte a todas as opções de mensagens disponíveis nas plataformas da Apple, do Android e da Web. Como cada plataforma tem o próprio bloco definido no payload JSON, o FCM pode ampliar a API para novas versões e plataformas conforme necessário.
Atualizar o endpoint do servidor
O URL do endpoint da API HTTP v1 é diferente do endpoint legado nos seguintes aspectos:
- A versão é controlada com
/v1
no caminho. - O caminho contém o ID do projeto do Firebase
do app no formato
/projects/myproject-ID/
. Esse ID está disponível na guia Configurações gerais do projeto no Console do Firebase. - Ele especifica explicitamente o método
send
como:send
.
Caso você queira atualizar o endpoint do servidor para HTTP v1, adicione estes elementos ao endpoint no cabeçalho das suas solicitações de envio.
Solicitações HTTP antes de
POST https://fcm.googleapis.com/fcm/send
Solicitações XMPP antes de
As mensagens XMPP legadas são enviadas por uma conexão com o seguinte endpoint:
fcm-xmpp.googleapis.com:5235
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 OAuth 2.0. Se você estiver usando o SDK Admin
para enviar mensagens, a biblioteca vai 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 nos 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 o aplicativo estiver sendo executado no Compute Engine, Google Kubernetes Engine, App Engine ou Cloud Functions, incluindo o Cloud Functions for Firebase, use o Application Default Credentials (ADC). O ADC usa sua conta de serviço padrão para receber credenciais e autorizar solicitações. Além disso, esse serviço permite testes locais flexíveis usando a variável de ambiente GOOGLE_APPLICATION_CREDENTIALS. Para uma automação mais completa do fluxo de autorização, use o ADC com as bibliotecas de servidor do SDK Admin.
Caso o seu aplicativo esteja 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. Se você tiver acesso a um sistema de arquivos com o arquivo de chave privada, você poderá usar a variável de ambiente GOOGLE_APPLICATION_CREDENTIALS para autorizar solicitações com as credenciais recebidas manualmente. Se você não tiver acesso a esse arquivo, será preciso referenciar o arquivo da conta de serviço no seu código. Tenha muito cuidado ao fazer isso, porque há risco de suas credenciais serem expostas.
Fornecer credenciais usando o ADC
O Application Default Credentials (ADC) do Google verifica suas credenciais na seguinte ordem:
O ADC verifica se a variável de ambiente GOOGLE_APPLICATION_CREDENTIALS está configurada. Caso esteja, o arquivo da conta de serviço indicado pela variável será usado.
Se a variável de ambiente não estiver definida, o ADC usará a conta de serviço padrão que Compute Engine, Google Kubernetes Engine, App Engine, e o Cloud Functions fornecem para aplicativos executados nesses serviços.
Se o ADC não puder usar nenhuma das credenciais acima, o sistema emitirá um erro.
O exemplo de código do SDK Admin a seguir 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, Google Kubernetes Engine, App Engine ou Cloud Functions.
Node.js
admin.initializeApp({
credential: admin.credential.applicationDefault(),
});
Java
FirebaseOptions options = 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 usando seu servidor de aplicativos ou um ambiente confiável. Se você estiver desenvolvendo código ou implantando o aplicativo localmente, será possível usar credenciais recebidas por essa 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:
No console Firebase, abra Configurações > Contas de serviço.
Clique em Gerar nova chave privada e selecione Gerar chave para confirmar.
Armazene com segurança o arquivo JSON que contém a chave.
Ao autorizar usando 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 gerar tokens de acesso
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 new Promise(function(resolve, reject) {
const key = require('../placeholders/service-account.json');
const 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);
});
});
}
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 = service_account.Credentials.from_service_account_file(
'service-account.json', scopes=SCOPES)
request = google.auth.transport.requests.Request()
credentials.refresh(request)
return credentials.token
Java
private static String getAccessToken() throws IOException {
GoogleCredentials googleCredentials = GoogleCredentials
.fromStream(new FileInputStream("service-account.json"))
.createScoped(Arrays.asList(SCOPES));
googleCredentials.refresh();
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 FCM, solicite o escopo
https://www.googleapis.com/auth/firebase.messaging
.
Para adicionar o token de acesso a um cabeçalho da 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 " + getServiceAccountAccessToken());
httpURLConnection.setRequestProperty("Content-Type", "application/json; UTF-8");
return httpURLConnection;
Atualizar o payload de solicitações de envio
A FCM HTTP v1 apresenta uma mudança significativa na estruturação do payload da mensagem 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 abaixo a comparação de um payload de notificação muito simples que contém apenas campos title
, body
e data
. Assim, será possível ver as diferenças fundamentais entre payloads legados 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: dados JSON aninhados
Ao contrário da API de mensagens legada, a API HTTP v1 não oferece suporte a valores JSON aninhados no campo data
.
É necessária uma conversão de JSON para string.
Antes
{
...
"data": {
"keysandvalues": {"key1": "value1", "key2": 123}
}
}
Depois
{
"message": {
...
"data": {
"keysandvalues": "{\"key1\": \"value1\", \"key2\": 123}"
}
}
}
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"
}
}
// Apple
{
"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"
}
},
"apns": {
"payload": {
"aps": {
"category" : "NEW_MESSAGE_CATEGORY"
}
}
}
}
}
Exemplo: personalização com substituições de plataforma
Além de simplificar a orientação a 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"
}
}
// Apple
{
"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"
}
}
}
}
}
Exemplo: segmentação de dispositivos específicos
Para segmentar dispositivos específicos com a API HTTP v1, forneça o token de registro atual do
dispositivo na chave token
em vez da chave to
.
Antes
{ "notification": {
"body": "This is an FCM notification message!",
"title": "FCM Message"
},
"to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
}
Depois
{
"message":{
"token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"notification":{
"body":"This is an FCM notification message!",
"title":"FCM Message"
}
}
}
Para mais exemplos e informações sobre a API HTTP v1 do FCM, consulte:
Orientação sobre como criar solicitações de envio do servidor de aplicativos com a API HTTP v1. Todos os snippets "REST" usam a API v1, a menos que especificado de outra maneira.