Ir para o console

Autorizar solicitações de envio

As solicitações enviadas para o FCM usando o servidor do app ou o ambiente confiável precisam ser autorizadas. Observe essas importantes diferenças entre a autorização herdada da API HTTP e HTTP v1:

  • A API FCM HTTP v1 autoriza solicitações com um token de acesso OAuth 2.0 de curta duração. Para produzir esse token, você pode usar o Application Default Credentials do Google (em ambientes de servidor do Google) e/ou conseguir manualmente as credenciais necessárias de um arquivo de chave privada JSON gerado para uma conta de serviço. Se você estiver usando o SDK Admin do Firebase para enviar mensagens, a biblioteca manipulará o token para você.
  • Os protocolos legados podem usar apenas chaves de API de longa duração recuperadas do Console do Firebase.

Autorizar solicitações de envio HTTP v1

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 o 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 o app 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.

Usar credenciais para produzir tokens de acesso

A menos que você esteja usando o SDK Admin, que gerencia a autorização automaticamente, será necessário produzir o token de acesso e adicioná-lo para enviar solicitações.

Use suas credenciais do Firebase na Biblioteca de cliente da API Google 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) {
    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;

Autorizar solicitações de envio de protocolo legado

Com o protocolo HTTP legado, cada solicitação precisa conter a chave do servidor disponível na guia Cloud Messaging do painel de Configurações do Console do Firebase. Para o XMPP, é preciso usar a mesma chave do servidor para estabelecer uma conexão.

Autorizar solicitações HTTP

Uma solicitação de mensagem consiste em duas partes: um cabeçalho HTTP e o corpo HTTP. O cabeçalho HTTP precisa conter os seguintes cabeçalhos:

  • Authorization: chave=CHAVE_DO_SEU_SERVIDOR
    Verifique se essa é a chave do servidor. O valor dela está disponível na guia Cloud Messaging do painel de Configurações do Console do Firebase. Chaves Android, iOS e de navegador são rejeitadas pelo FCM.
  • Content-Type: application/json para JSON; application/x-www-form-urlencoded;charset=UTF-8 para texto simples.
    Se Content-Type for omitido, o formato é considerado texto simples.

Por exemplo:

Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA

{
  "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
  "data" : {
    ...
  },
}

Consulte Criar solicitações de envio para detalhes completos sobre a criação de solicitações de envio. A Referência de protocolo HTTP legado oferece uma lista com todos os parâmetros que sua mensagem pode conter.

Verificar a validade de uma chave de servidor

Se você encontrar erros de autenticação durante o envio de mensagens, verifique a validade da chave de servidor. Por exemplo, no Linux, execute o seguinte comando:

api_key=YOUR_SERVER_KEY

curl --header "Authorization: key=$api_key" \
     --header Content-Type:"application/json" \
     https://fcm.googleapis.com/fcm/send \
     -d "{\"registration_ids\":[\"ABC\"]}"

Se você receber um código de status HTTP 401, a chave do servidor é inválida.

Autorizar uma conexão XMPP

Com o XMPP, você pode manter uma conexão permanente, assíncrona e bidirecional com servidores FCM. A conexão pode ser usada para enviar e receber mensagens entre o servidor e os dispositivos conectados ao FCM dos seus usuários.

Você pode usar a maioria das bibliotecas XMPP para gerenciar uma conexão fixa com o FCM. O ponto de extremidade de XMPP é executado na porta fcm-xmpp.googleapis.com:5235. Para testar a funcionalidade com usuários fora do ambiente de produção, conecte-se ao servidor de pré-produção na porta fcm-xmpp.googleapis.com:5236 (observe que a porta é diferente).

O benefício do teste normal em pré-produção (um ambiente menor com as versões mais recentes do FCM em execução) é isolar os usuários reais do código de teste. Os dispositivos de teste e o código de teste conectados à porta fcm-xmpp.googleapis.com:5236 precisam utilizar um código de emissor do FCM diferente para evitar o risco de enviar mensagens de teste para usuários em produção ou enviar mensagens upstream do tráfego de produção usando conexões de teste.

A conexão tem dois requisitos importantes:

  • É preciso iniciar uma conexão com o protocolo TLS. Observe que atualmente o FCM não é compatível com a extensão STARTTLS.
  • O FCM exige um mecanismo de autenticação SASL PLAIN usando <your_FCM_Sender_Id>@fcm.googleapis.com (código do remetente do FCM) e a chave do servidor como a senha. Esses valores estão disponíveis na guia Cloud Messaging do painel de Configurações do Console do Firebase.

Se a conexão falhar em algum momento, será preciso reconectar imediatamente. Não é preciso esperar após uma desconexão que ocorra após a autenticação. Para cada código do remetente, o FCM permite 1.000 conexões paralelas.

Os snippets a seguir ilustram como executar autenticação e autorização para uma conexão XMPP ao FCM.

Servidor XMPP

O servidor XMPP solicita uma conexão ao FCM

<stream:stream to="fcm.googleapis.com"
        version="1.0" xmlns="jabber:client"
        xmlns:stream="http://etherx.jabber.org/streams">

FCM

O FCM abre a conexão e solicita um mecanismo auth, incluindo o método PLAIN.

<stream:features>
  <mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl">
    <mechanism>X-OAUTH2</mechanism>
    <mechanism>X-GOOGLE-TOKEN</mechanism>
    <mechanism>PLAIN</mechanism>
  </mechanisms>
</stream:features>

Servidor XMPP

O servidor XMPP precisa responder por meio do método de autenticação PLAIN, fornecendo a chave do servidor na guia Cloud Messaging do painel de Configurações do Console do Firebase.

<auth mechanism="PLAIN"
xmlns="urn:ietf:params:xml:ns:xmpp-sasl">MTI2MjAwMzQ3OTMzQHByb2plY3RzLmdjbS5hb
mFTeUIzcmNaTmtmbnFLZEZiOW1oekNCaVlwT1JEQTJKV1d0dw==</auth>

FCM

<success xmlns="urn:ietf:params:xml:ns:xmpp-sasl"/>

Servidor XMPP

<stream:stream to="fcm.googleapis.com"
        version="1.0" xmlns="jabber:client"
        xmlns:stream="http://etherx.jabber.org/streams">

FCM

<stream:features>
  <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"/>
  <session xmlns="urn:ietf:params:xml:ns:xmpp-session"/>
</stream:features>

Servidor XMPP

<iq type="set">
  <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"></bind>
</iq>

FCM

<iq type="result">
  <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
    <jid>SENDER_ID@fcm.googleapis.com/RESOURCE</jid>
  </bind>
</iq>

Observação: o FCM não usa o recurso vinculado ao encaminhar mensagens.

Consulte Criar solicitações de envio para detalhes completos sobre a criação de solicitações de envio. Na Referência de protocolo XMPP legado, você encontra uma lista de todos os parâmetros que sua mensagem pode conter.