Acompanhe tudo o que foi anunciado no Firebase Summit e saiba como usar o Firebase para acelerar o desenvolvimento de apps e executá-los com confiança. Saiba mais

Seu ambiente de servidor e FCM

O lado do servidor do Firebase Cloud Messaging consiste em dois componentes:

  • O back- end do FCM fornecido pelo Google.
  • Seu servidor de aplicativos ou outro ambiente de servidor confiável em que a lógica do servidor é executada, como o Cloud Functions para Firebase ou outros ambientes de nuvem gerenciados pelo Google.

Seu servidor de aplicativos ou ambiente de servidor confiável envia solicitações de mensagens para o back-end do FCM, que roteia mensagens para aplicativos cliente executados nos dispositivos dos usuários.

Requisitos para o ambiente de servidor confiável

Seu ambiente de servidor de aplicativos deve atender aos seguintes critérios:

  • Capaz de enviar solicitações de mensagens formatadas corretamente para o back-end do FCM.
  • Capaz de lidar com solicitações e reenviá-las usando back-off exponencial.
  • Capaz de armazenar com segurança credenciais de autorização do servidor e tokens de registro do cliente.
  • Para o protocolo XMPP (se usado), o servidor deve ser capaz de gerar IDs de mensagem para identificar exclusivamente cada mensagem enviada (o back-end HTTP do FCM gera IDs de mensagem e os retorna na resposta). Os IDs de mensagens XMPP devem ser exclusivos por ID de remetente.

Escolhendo uma opção de servidor

Você precisará decidir uma maneira de interagir com os servidores FCM: usando o SDK Admin do Firebase ou os protocolos brutos. Por causa de seu suporte em linguagens de programação populares e seus métodos convenientes para lidar com autenticação e autorização, o SDK Admin do Firebase é o método recomendado.

As opções para interagir com servidores FCM incluem o seguinte:

  • O SDK Admin do Firebase, que tem suporte para Node , Java , Python , C# e Go .
  • A API HTTP v1 do FCM , que é a mais atualizada das opções de protocolo, com autorização mais segura e recursos flexíveis de mensagens entre plataformas (o SDK Admin do Firebase é baseado nesse protocolo e oferece todas as suas vantagens inerentes). Como os novos recursos normalmente são adicionados apenas à API HTTP v1, recomendamos usar essa API para a maioria dos casos de uso.
  • O protocolo HTTP legado . Novos projetos são altamente recomendados para adotar a API HTTP do FCM v1 em vez do protocolo legado.
  • O protocolo de servidor XMPP legado . Novos projetos são altamente recomendados para adotar a API HTTP do FCM v1 em vez do protocolo legado.

SDK Admin do Firebase para FCM

A API Admin FCM lida com a autenticação com o back-end e facilita o envio de mensagens e o gerenciamento de assinaturas de tópicos. Com o SDK Admin do Firebase, você pode:

  • Envie mensagens para dispositivos individuais
  • Envie mensagens para tópicos e declarações de condição que correspondam a um ou mais tópicos.
  • Inscrever e cancelar a inscrição de dispositivos de e para tópicos
  • Construir cargas úteis de mensagens personalizadas para diferentes plataformas de destino

O SDK Admin Node.js fornece métodos para enviar mensagens para grupos de dispositivos.

Para configurar o SDK Admin do Firebase, consulte Adicionar o SDK Admin do Firebase ao seu servidor . Se você já tem um projeto do Firebase, comece com Adicionar o SDK . Além disso, certifique-se de ativar a API Cloud Messagin na página de configurações do Cloud Messaging para seu projeto. Depois que o SDK Admin do Firebase estiver instalado, você poderá começar a escrever a lógica para criar solicitações de envio .

Protocolos do servidor FCM

Atualmente, o FCM fornece estes protocolos de servidor bruto:

Seu servidor de aplicativos pode usar esses protocolos separadamente ou em conjunto. Por ser a mais atualizada e flexível para enviar mensagens para várias plataformas, a API HTTP v1 do FCM é recomendada sempre que possível. Se seus requisitos incluem mensagens upstream de dispositivos para o servidor, você precisará implementar o protocolo XMPP.

As mensagens XMPP diferem das mensagens HTTP das seguintes maneiras:

  • Mensagens upstream/downstream
    • HTTP: somente downstream, nuvem para dispositivo.
    • XMPP: upstream e downstream (dispositivo para nuvem, nuvem para dispositivo).
  • Mensagens (síncronas ou assíncronas)
    • HTTP: Síncrono. Os servidores de aplicativos enviam mensagens como solicitações HTTP POST e aguardam uma resposta. Esse mecanismo é síncrono e bloqueia o remetente de enviar outra mensagem até que a resposta seja recebida.
    • XMPP: Assíncrono. Os servidores de aplicativos enviam/recebem mensagens de/para todos os seus dispositivos em velocidade de linha total em conexões XMPP persistentes. O servidor de conexão XMPP envia notificações de reconhecimento ou falha (na forma de mensagens especiais XMPP codificadas em ACK e NACK JSON) de forma assíncrona.
  • JSON
    • HTTP: mensagens JSON enviadas como HTTP POST.
    • XMPP: mensagens JSON encapsuladas em mensagens XMPP.
  • Texto simples
    • HTTP: mensagens de texto simples enviadas como HTTP POST.
    • XMPP: Não suportado.
  • Envio downstream multicast para vários tokens de registro.
    • HTTP: com suporte no formato de mensagem JSON.
    • XMPP: Não suportado.

Implementando o protocolo do servidor HTTP

Para enviar uma mensagem, o servidor de aplicativos emite uma solicitação POST com um cabeçalho HTTP e um corpo HTTP composto por pares de valores de chave JSON. Para obter detalhes sobre as opções de cabeçalho e corpo, consulte Build App Server Send Requests

Implementando o protocolo do servidor XMPP

A carga JSON para mensagens FCM é semelhante ao protocolo HTTP, com estas exceções:

  • Não há suporte para vários destinatários.
  • O FCM adiciona o campo message_id , que é obrigatório. Esse ID identifica exclusivamente a mensagem em uma conexão XMPP. O ACK ou NACK do FCM usa o message_id para identificar uma mensagem enviada dos servidores de aplicativos para o FCM. Portanto, é importante que esse message_id não seja apenas exclusivo (por ID do remetente ), mas sempre presente.
  • O XMPP usa a chave do servidor para autorizar uma conexão persistente com o FCM. Consulte Autorizar solicitações de envio para obter mais informações.

Além das mensagens regulares do FCM, são enviadas mensagens de controle, indicadas pelo campo message_type no objeto JSON. O valor pode ser 'ack' ou 'nack', ou 'control' (veja os formatos abaixo). Qualquer mensagem do FCM com um tipo de mensagem desconhecido pode ser message_type pelo seu servidor.

Para cada mensagem de dispositivo que seu servidor de aplicativos recebe do FCM, ele precisa enviar uma mensagem ACK. Ele nunca precisa enviar uma mensagem NACK. Se você não enviar um ACK para uma mensagem, o FCM o reenviará na próxima vez que uma nova conexão XMPP for estabelecida, a menos que a mensagem expire primeiro.

O FCM também envia um ACK ou NACK para cada mensagem de servidor para dispositivo. Se você também não receber, significa que a conexão TCP foi fechada no meio da operação e seu servidor precisa reenviar as mensagens. Consulte Controle de fluxo para obter detalhes.

Consulte a Referência de protocolo para obter uma lista de todos os parâmetros de mensagem.

Formato de solicitação

Mensagem com carga útil — mensagem de notificação

Aqui está uma estrofe XMPP para uma mensagem de notificação:

<message id="">
  <gcm xmlns="google:mobile:data">
  {
     "to":"REGISTRATION_ID",  // "to" replaces "registration_ids"
     "notification": {
        "title": "Portugal vs. Denmark”,
        "body”: "5 to 1”
      },
      "time_to_live":"600"
  }
  </gcm>
</message>

Mensagem com carga útil — mensagem de dados

Aqui está uma estrofe XMPP contendo a mensagem JSON de um servidor de aplicativos para o FCM:

<message id="">
  <gcm xmlns="google:mobile:data">
  {
      "to":"REGISTRATION_ID",  // "to" replaces "registration_ids"
      "message_id":"m-1366082849205" // new required field
      "data":
      {
          "hello":"world",
      }
      "time_to_live":"600",
  }
  </gcm>
</message>

Formato de resposta

Uma resposta FCM pode ter três formas possíveis. A primeira é uma mensagem 'ack' normal. Mas quando a resposta contém um erro, existem 2 formas diferentes que a mensagem pode assumir, descritas abaixo.

mensagem de confirmação

Aqui está uma estrofe XMPP contendo a mensagem ACK/NACK do FCM para o servidor de aplicativos:

<message id="">
  <gcm xmlns="google:mobile:data">
  {
      "from":"REGID",
      "message_id":"m-1366082849205"
      "message_type":"ack"
  }
  </gcm>
</message>

NACK mensagem

Um erro NACK é uma mensagem XMPP regular na qual a mensagem de status message_type é "nack". Uma mensagem NACK contém:

  • Um código de erro NACK.
  • Uma descrição de erro NACK.

Abaixo estão alguns exemplos.

Registro incorreto:

<message>
  <gcm xmlns="google:mobile:data">
  {
    "message_type":"nack",
    "message_id":"msgId1",
    "from":"SomeInvalidRegistrationToken",
    "error":"BAD_REGISTRATION",
    "error_description":"Invalid token on 'to' field: SomeInvalidRegistrationId"
  }
  </gcm>
</message>

JSON inválido:

<message>
 <gcm xmlns="google:mobile:data">
 {
   "message_type":"nack",
   "message_id":"msgId1",
   "from":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
   "error":"INVALID_JSON",
   "error_description":"InvalidJson: JSON_TYPE_ERROR : Field \"time_to_live\" must be a JSON java.lang.Number: abc"
 }
 </gcm>
</message>

Taxa de mensagens do dispositivo excedida:

<message id="...">
  <gcm xmlns="google:mobile:data">
  {
    "message_type":"nack",
    "message_id":"msgId1",
    "from":"REGID",
    "error":"DEVICE_MESSAGE_RATE_EXCEEDED",
    "error_description":"Downstream message rate exceeded for this registration id"
  }
  </gcm>
</message>

Consulte a Referência do Servidor para obter uma lista completa dos códigos de erro NACK. Salvo indicação em contrário, uma mensagem NACK não deve ser repetida. Códigos de erro NACK inesperados devem ser tratados da mesma forma que INTERNAL_SERVER_ERROR .

Erro de estrofe

Você também pode obter um erro de estrofe em certos casos. Um erro de estrofe contém:

  • Código de erro da estrofe.
  • Descrição do erro de estrofe (texto livre).

Por exemplo:

<message id="3" type="error" to="123456789@fcm.googleapis.com/ABC">
  <gcm xmlns="google:mobile:data">
     {"random": "text"}
  </gcm>
  <error code="400" type="modify">
    <bad-request xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
    <text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas">
      InvalidJson: JSON_PARSING_ERROR : Missing Required Field: message_id\n
    </text>
  </error>
</message>

Mensagens de controle

Periodicamente, o FCM precisa encerrar uma conexão para realizar o balanceamento de carga. Antes de fechar a conexão, o FCM envia uma mensagem CONNECTION_DRAINING para indicar que a conexão está sendo drenada e será fechada em breve. "Drenagem" refere-se a desligar o fluxo de mensagens que entram em uma conexão, mas permitindo que o que já está no pipeline continue. Ao receber uma mensagem CONNECTION_DRAINING , você deve começar imediatamente a enviar mensagens para outra conexão FCM, abrindo uma nova conexão se necessário. Você deve, no entanto, manter a conexão original aberta e continuar recebendo mensagens que podem vir pela conexão (e reconhecendo-as)—o FCM trata de iniciar uma conexão fechada quando estiver pronta.

A mensagem CONNECTION_DRAINING tem esta aparência:

<message>
  <data:gcm xmlns:data="google:mobile:data">
  {
    "message_type":"control"
    "control_type":"CONNECTION_DRAINING"
  }
  </data:gcm>
</message>

CONNECTION_DRAINING é atualmente o único control_type suportado.

Controle de fluxo

Cada mensagem enviada ao FCM recebe uma resposta ACK ou NACK. As mensagens que não receberam uma dessas respostas são consideradas pendentes. Se a contagem de mensagens pendentes atingir 100, o servidor de aplicativos deve parar de enviar novas mensagens e aguardar que o FCM reconheça algumas das mensagens pendentes existentes, conforme ilustrado na figura 1:

Diagrama detalhado do fluxo de controle entre o FCM e o servidor de aplicativos

Figura 1. Fluxo de mensagem/confirmação.

Por outro lado, para evitar sobrecarregar o servidor de aplicativos, o FCM para de enviar se houver muitas mensagens não confirmadas. Portanto, o servidor de aplicativos deve "ACK" mensagens upstream, recebidas do aplicativo cliente via FCM, o mais rápido possível para manter um fluxo constante de mensagens recebidas. O limite de mensagens pendentes mencionado acima não se aplica a esses ACKs. Mesmo que a contagem de mensagens pendentes atinja 100, o servidor de aplicativos deve continuar enviando ACKs para mensagens recebidas do FCM para evitar o bloqueio da entrega de novas mensagens upstream.

ACKs são válidos apenas no contexto de uma conexão. Se a conexão for fechada antes que uma mensagem possa ser ACK, o servidor de aplicativos deverá aguardar que o FCM reenvie a mensagem upstream antes de ACK novamente. Da mesma forma, todas as mensagens pendentes para as quais um ACK/NACK não foi recebido do FCM antes do fechamento da conexão devem ser enviadas novamente.