获取我们在 Firebase 峰会上发布的所有信息,了解 Firebase 可如何帮助您加快应用开发速度并满怀信心地运行应用。了解详情

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 onde sua lógica de servidor é executada, como 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 encaminha mensagens para aplicativos clientes em execução 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 mensagem 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 as credenciais de autorização do servidor e os 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 FCM HTTP gera IDs de mensagem e os retorna na resposta). Os IDs de mensagem XMPP devem ser exclusivos por ID de remetente.

Escolhendo uma opção de servidor

Você precisará decidir sobre uma maneira de interagir com os servidores FCM: usando o Firebase Admin SDK 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 Firebase Admin SDK é o método recomendado.

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

  • O Firebase Admin SDK, compatível com Node , Java , Python , C# e Go .
  • A API FCM HTTP v1 , que é a mais atualizada das opções de protocolo, com autorização mais segura e recursos flexíveis de mensagens entre plataformas (o Firebase Admin SDK é baseado nesse protocolo e oferece todas as suas vantagens inerentes). Como os novos recursos geralmente são adicionados apenas à API HTTP v1, recomendamos o uso dessa API para a maioria dos casos de uso.
  • O protocolo HTTP herdado . Novos projetos são fortemente recomendados para adotar a API HTTP FCM v1 em vez do protocolo legado.
  • O protocolo legado do servidor XMPP . Novos projetos são fortemente recomendados para adotar a API HTTP 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 Firebase Admin SDK, você pode:

  • Enviar 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 payloads de mensagens personalizados para diferentes plataformas de destino

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

Para configurar o Firebase Admin SDK, consulte Adicionar o Firebase Admin SDK ao seu servidor . Se você já tem um projeto Firebase, comece com Add the SDK . Além disso, certifique-se de ativar a API do Cloud Messaging na página de configurações do Cloud Messaging para seu projeto. Depois que o Firebase Admin SDK 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 esses 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 FCM HTTP v1 é recomendada sempre que possível. Se seus requisitos incluírem 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 impede que o remetente envie 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 máxima de linha em conexões XMPP persistentes. O servidor de conexão XMPP envia notificações de confirmação ou falha (na forma de mensagens XMPP codificadas em ACK e NACK JSON especiais) 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 sem formatação enviadas como HTTP POST.
    • XMPP: não suportado.
  • Envio downstream multicast para vários tokens de registro.
    • HTTP: Suportado 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-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 as seguintes exceções:

  • Não há suporte para vários destinatários.
  • O FCM adiciona o campo message_id , que é obrigatório. Essa 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 único (por ID do remetente ), mas esteja 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 FCM regulares, 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 FCM com um message_type desconhecido pode ser ignorada 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 do servidor para o dispositivo. Se você não receber nenhum dos dois, significa que a conexão TCP foi encerrada 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 — 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 — 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 regular de 'ack'. Mas quando a resposta contém um erro, existem 2 formas diferentes que a mensagem pode assumir, descritas abaixo.

mensagem ACK

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>

mensagem NACK

Um erro NACK é uma mensagem XMPP normal 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 da 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 encerrar a conexão, o FCM envia uma mensagem CONNECTION_DRAINING para indicar que a conexão está sendo drenada e será encerrada em breve. "Drenar" refere-se a interromper o fluxo de mensagens que entram em uma conexão, mas permitir 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 possam vir pela conexão (e reconhecê-las) — o FCM lida com o início de um fechamento de conexão quando estiver pronto.

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 chegar a 100, o servidor do aplicativo deve parar de enviar novas mensagens e esperar 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 interrompe o envio se houver muitas mensagens não confirmadas. Portanto, o servidor de aplicativos deve "ACK" as 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 chegue a 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 reconhecida, o servidor de aplicativos deve aguardar que o FCM reenvie a mensagem upstream antes de reconhecê-la 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.