Sending Upstream Messages on iOS

If your app server implements the XMPP Connection Server protocol, it can receive upstream messages from a user's device to the cloud. To initiate an upstream message, the client app sends a request containing the following:

  • The address of the receiving app server in the format SENDER_ID@gcm.googleapis.com.
  • A message ID that should be unique for each sender ID.
  • The message data comprising the key-value pairs of the message's payload.

When it receives this data, FCM builds an XMPP stanza to send to the app server, adding some additional information about the sending device and app.

Send an upstream message from an iOS client app

To send messages upstream to the server, an iOS client app composes a message and calls sendMessage as shown:

Objective-C

[[FIRMessaging messaging] sendMessage:message
                                   to:receiver
                        withMessageID:messageID
                           timeToLive:ttl];

Swift

FIRMessaging.messaging().sendMessage(message,
                                     to: to,
                                     withMessageID: messageId,
                                     timeToLive: ttl)

where:

  • to is the address of the receiving app server in the format SENDER_ID@gcm.googleapis.com.

  • withMessageID is a unique message identifier. All the message receiver callbacks are identified on the basis of this message ID.

  • message is a dictionary of keys and values as strings. Any key-value pair that is not a string is ignored.

  • timeToLive is the time to live. If FCM can't deliver the message before this expiration is reached, it sends a notification back to the client.

The FCM client library caches the message on the client app and sends it when the client has an active server connection. On receiving the message, the FCM connection server sends it to the app server.

Handle upstream message callbacks

Handle upstream callbacks by adding observers that listen for sendDataMessageFailure and sendDataMessageSuccess, and then retrieve error information from the selectors. In this example, FIRMessagingSendErrorNotification is the selector used to handle the callback:

- (void)sendDataMessageFailure:(NSNotification *)notification {
  NSString *messageID = (NSString *)message.object;
}
- (void)sendDataMessageSuccess:(NSNotification *)notification {
  NSString *messageID = (NSString *)message.object;
  NSDictionary *userInfo = message.userInfo; // contains error info etc
}

To optimize network usage, FCM batches responses to sendDataMessageFailure and sendDataMessageSuccess, so the acknowledgement may not be immediate for each message.

Receive XMPP messages on the app server

When FCM receives an upstream messaging call from a client app, it generates the necessary XMPP stanza for sending the upstream message. FCM adds the category and from fields, and then sends a stanza like the following to the app server:

<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>

Sending an ACK message

In response to an upstream message like the above, the app server must use the same connection to send an ACK message containing the unique message ID. If FCM does not receive an ACK, it may retry sending the message to the app server.

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

See the XMPP Connection Server Reference for more information about upstream message syntax.

Send feedback about...

Need help? Visit our support page.