Como enviar mensagens upstream no Android

Se o servidor do app implementar o protocolo do servidor de conexão XMPP, ele poderá receber mensagens upstream do dispositivo do usuário para a nuvem. Para iniciar essa mensagem, o app cliente envia uma solicitação contendo:

  • o endereço do servidor do app de destino no formato SENDER_ID@fcm.googleapis.com;
  • Um ID da mensagem que deve ser exclusivo para cada ID do remetente.
  • Os dados da mensagem, inclusive os pares de chave/valor do payload da mensagem.

Ao receber esses dados, o FCM cria uma estrofe XMPP para enviar ao servidor do app, acrescentando algumas informações adicionais sobre o app e o dispositivo emissor.

Enviar uma mensagem upstream de um app cliente Android

Seu app Android pode enviar uma mensagem upstream utilizando FirebaseMessaging.send:

Kotlin+KTX

val fm = Firebase.messaging
fm.send(
    remoteMessage("$SENDER_ID@fcm.googleapis.com") {
        setMessageId(messageId.toString())
        addData("my_message", "Hello World")
        addData("my_action", "SAY_HELLO")
    },
)

Java

FirebaseMessaging fm = FirebaseMessaging.getInstance();
fm.send(new RemoteMessage.Builder(SENDER_ID + "@fcm.googleapis.com")
        .setMessageId(Integer.toString(messageId))
        .addData("my_message", "Hello World")
        .addData("my_action","SAY_HELLO")
        .build());

Processar callbacks de mensagens upstream

Com o FirebaseMessaging, é possível implementar os callbacks onMessageSent e onSendError para verificar o status das mensagens upstream. Em casos de erro, onSendError retorna um SendException com um código de erro. Por exemplo, se o cliente tentar enviar mais mensagens após exceder o limite de 20 mensagens, a mensagem SendException#ERROR_TOO_MANY_MESSAGES será retornada.

Quando o dispositivo estiver off-line ou o serviço do FCM não estiver disponível para encaminhar mensagens upstream para o servidor, as instâncias de apps cliente Android poderão acumular no máximo 20 mensagens pendentes. Se essas mensagens expirarem antes que o FCM possa enviá-las com sucesso, o onSendError retornará SendException#ERROR_TTL_EXCEEDED.

Para otimizar o uso da rede, o FCM lança respostas para onMessageSent e onSendError. Portanto, a confirmação pode não ser imediata para cada mensagem.

Receber mensagens XMPP no servidor de aplicativos

Quando uma chamada de mensagem upstream de um app cliente é recebida no FCM, é gerada uma estrofe XMPP para enviar essa mensagem. Os campos category e from são adicionados pelo FCM, que envia uma estrofe como esta ao servidor do app:

<message id="">
  <gcm xmlns="google:mobile:data">
  {
      "category":"com.example.yourapp", // to know which app sent it
      "data":
      {
          "hello":"world",
      },
      "message_id":"m-123",
      "from":"REGID"
  }
  </gcm>
</message>

Como enviar mensagens ACK

Em resposta a uma mensagem upstream como a mostrada acima, o servidor do app deve usar a mesma conexão para enviar uma ACK com o ID exclusivo da mensagem. Se o FCM não receber uma ACK, pode ser que ele tente enviar a mensagem para o servidor do app novamente.

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

Consulte Referência do servidor de conexão XMPP para mais informações sobre a sintaxe de mensagens upstream.