Firebase Cloud Messaging (FCM) is the new version of GCM. It inherits the reliable and scalable GCM infrastructure, plus new features! See the FAQ to learn more. If you are integrating messaging in a new app, start with FCM. GCM users are strongly recommended to upgrade to FCM, in order to benefit from new FCM features today and in the future. Before you go, please visit our GCM and FCM developer survey to give us feedback!

Send Upstream Messages

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 per sender ID.
  • The message data comprising the key/value pairs of the message's payload.

When it receives this data, GCM 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 Android client app

Your Android app can send an upstream message using the GoogleCloudMessaging API to call gcm.send as shown:

public void onClick(final View view) {
    if (view == findViewById(R.id.send)) {
        new AsyncTask() {
            @Override
            protected String doInBackground(Void... params) {
                String msg = "";
                try {
                    Bundle data = new Bundle();
                    data.putString("my_message", "Hello World");
                    data.putString("my_action","SAY_HELLO");
                    String id = Integer.toString(msgId.incrementAndGet());
                    gcm.send(SENDER_ID + "@gcm.googleapis.com", id, data);
                    msg = "Sent message";
                } catch (IOException ex) {
                    msg = "Error :" + ex.getMessage();
                }
                return msg;
            }

            @Override
            protected void onPostExecute(String msg) {
                mDisplay.append(msg + "\n");
            }
        }.execute(null, null, null);
    } else if (view == findViewById(R.id.clear)) {
        mDisplay.setText("");
    }
}

To see similar Android code in the context of a demo application, see gcm-demo on GitHub.

Handle upstream message callbacks

With GcmListenerService, you can implement the callbacks onMessageSent and onSendError to check the status of upstream messages. Keep in mind that GCM batches responses from onMessageSent, so the acknowledgement may not be immediate for each successfully sent message.

In cases where the device is offline or the GCM service is unavailable to forward upstream messages to your server, Android client app instances can accumulate a maximum of 20 pending messages.

If such messages expire before GCM can successfully send them, onSendError returns GoogleCloudMessaing#ERROR_SERVICE_NOT_AVAILABLE. If the client attempts to send more messages after the 20-message limit is reached, it returns GoogleCloudMessaing#TooManyMessages.

Send upstream messages from an iOS client app

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

// a unique global identifier for each message sent
int nextMessageID = self.messagesSent++;
NSDictionary *message = @{
  @"user" : [NSString stringWithFormat:"%lld", userID],
  @"hello" : @"world"
};
// kSenderID is the senderID you want to send the message to
NSString *to = [[NSString stringWithFormat:@"%@@gcm.googleapis.com", kSenderID];

[[GCMService sharedInstance] sendTo:to
                      withMessageID:nextMessageID
                               data:message];

where:

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

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

  • data is a dictionary of keys and values as strings. Any key or value pair that is not a string will be ignored.

The GCM 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 GCM connection server sends it to the app server.

Handle upstream message callbacks

The GCMReceiverDelegate protocol declares two methods to check the status of upstream messages and verify when they are ready to send, whether they have been successfully processed, or whether they were not sent for specific failure conditions:

- (void)willSendDataMessageWithID:(NSString *)messageID error:(NSError *)error {
  if (error) {
    // Failed to send the message.
  } else {
    // Will send message, you can save the messageID to track the message
  }
}

- (void)didSendDataMessageWithID:(NSString *)messageID {
  // Did successfully send message identified by messageID
}

To handle these callbacks you need to:

  1. Declare a class that adopts the GCMReceiverDelegate protocol
  2. Set that class as your receiver delegate on your GCMConfig using the receiverDelegate property.

The method willSendDataMessageWithID is invoked when the GCM client library has processed the upstream message. The message is either:

  • ready to be sent, or the GCM client library encounters an error during processing and cannot send the message.

  • messageID identifies the message that has been processed.

  • error represents the error codes if the GCM client library encounters a send error. See Common error codes for more information.

The method didSendDataMessageWithID is invoked when GCM has sent the message successfully. If there is an error during send, GCM retries.

Receive XMPP messages on the app server

When GCM receives an upstream messaging call from a client app, it generates the necessary XMPP stanza for sending the upstream message. GCM 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 GCM 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...

Cloud Messaging
Cloud Messaging