Overview

Google Cloud Messaging (GCM) is a free service that enables developers to send downstream messages (from servers to GCM-enabled client apps), and upstream messages (from the GCM-enabled client apps to servers). This could be a lightweight message telling the client app that there is new data to be fetched from the server (for instance, a "new email" notification informing the app that it is out of sync with the back end), or it could be a message containing up to 4kb of payload data (so apps like instant messaging can consume the message directly). The GCM service handles all aspects of queueing of messages and delivery to and from the target client app.

Key Concepts

This table summarizes the key terms and concepts involved in GCM. It is divided into these categories:

  • Components — The entities that play a primary role in GCM.
  • Credentials — The IDs and tokens that are used in GCM to ensure that all parties have been authenticated, and that the message is going to the correct place.

Table 1. GCM components and credentials.

Components
GCM Connection Servers The Google-provided servers involved in sending messages between the 3rd-party app server and the client app.
Client App A GCM-enabled client app that communicates with a 3rd-party app server.
3rd-party App Server An app server that you write as part of implementing GCM. The 3rd-party app server sends data to a client app via the GCM connection server.
Credentials
Sender ID A project number you acquire from the API console, as described in Getting Started. The sender ID is used in the registration process to identify a 3rd-party app server that is permitted to send messages to the client app.
Sender Auth Token An API key that is saved on the 3rd-party app server that gives the app server authorized access to Google services. The API key is included in the header of POST requests.
Application ID The client app that is registering to receive messages. How this is implemented is platform-dependent. For example, an Android app is identified by the package name from the manifest. This ensures that the messages are targeted to the correct Android app.
Registration ID An ID issued by the GCM servers to the client app that allows it to receive messages. Note that registration IDs must be kept secret.

Architectural Overview

A GCM implementation includes a Google-provided connection server, a 3rd-party app server that interacts with the connection server, and a GCM-enabled client app. For example, this diagram shows GCM communicating with a client app on an Android device:

Figure 1. GCM Architecture.

This is how these components interact:

  • Google-provided GCM Connection Servers take messages from a 3rd-party app server and send these messages to a GCM-enabled client app (the "client app"). Currently Google provides connection servers for HTTP and XMPP.
  • The 3rd-Party App Server is a component that you implement to work with your chosen GCM connection server(s). App servers send messages to a GCM connection server; the connection server enqueues and stores the message, and then sends it to the client app. For more information, see Implementing GCM Server.
  • The Client App is a GCM-enabled client app. To receive GCM messages, this app must register with GCM and get a registration ID. If you are using the XMPP (CCS) connection server, the client app can send "upstream" messages back to the 3rd-party app server. For more information on how to implement the client app, see the documentation for your platform.

Lifecycle Flow

  • Register to enable GCM. A client app registers to receive messages. For more discussion, see Register to enable GCM.
  • Send and receive downstream messages.
    • Send a message. A 3rd-party app server sends messages to the client app:
      1. The 3rd-party app server sends a message to GCM connection servers.
      2. The GCM connection server enqueues and stores the message if the device is offline.
      3. When the device is online, the GCM connection server sends the message to the device.
      4. On the device, the client app receives the message according to the platform-specific implementation. See your platform-specific documentation for details.
    • Receive a message. A client app receives a message from a GCM server. See your platform-specific documentation for details on how a client app in that environment processes the messages it receives.
  • Send and receive upstream messages. This feature is only available if you're using the XMPP Cloud Connection Server (CCS).
    • Send a message. A client app sends messages to the 3rd-party app server:
      1. On the device, the client app sends messages to XMPP (CCS).See your platform-specific documentation for details on how a client app can send a message to XMPP (CCS).
      2. XMPP (CCS) enqueues and stores the message if the server is disconnected.
      3. When the 3rd-party app server is re-connected, XMPP (CCS) sends the message to the 3rd-party app server.
    • Receive a message. A 3rd-party app server receives a message from XMPP (CCS) and then does the following:
      1. Parses the message header to verify client app sender information.
      2. Sends "ack" to GCM XMPP connection server to acknowledge receiving the message.
      3. Optionally parses the message payload, as defined by the client app.

Register to enable GCM

Regardless of the platform you're developing on, the first step a client app must do is register with GCM. This section covers some of the general best practices for registration and unregistration. See your platform-specific docs for details on writing a GCM-enabled client app on that platform.

Keeping the Registration State in Sync

Whenever the app registers as described in Implementing GCM Client, it should save the registration ID for future use, pass it to the 3rd-party server to complete the registration, and keep track of whether the server completed the registration. If the server fails to complete the registration, the client app should retry passing the registration ID to 3rd-party app server to complete the registration. If this continues to fail, the client app should unregister from GCM.

There are also two other scenarios that require special care:

  • Client app update
  • Backup and restore

Client app update: When a client app is updated, it should invalidate its existing registration ID, as it is not guaranteed to work with the new version. The recommended way to achieve this validation is by storing the current app version when a registration ID is stored. Then when the app starts, compare the stored value with the current app version. If they do not match, invalidate the stored data and start the registration process again.

Backup and restore: You should not save the registration ID when an app is backed up. This is because the registration ID could become invalid by the time the app is restored, which would put the app in an invalid state (that is, the app thinks it is registered, but the server and GCM do not store that registration ID anymore—thus the app will not get more messages). The best practice is to initiate the registration process as if the app has been installed for the first time.

Canonical IDs

If a bug in the app triggers multiple registrations for the same device, it can be hard to reconcile state and you might end up with duplicate messages.

GCM provides a facility called "canonical registration IDs" to easily recover from these situations. A canonical registration ID is defined to be the ID of the last registration requested by your app. This is the ID that the server should use when sending messages to the device.

If later on you try to send a message using a different registration ID, GCM will process the request as usual, but it will include the canonical registration ID in the registration_id field of the response. Make sure to replace the registration ID stored in your server with this canonical ID, as eventually the ID you're using will stop working.

Automatic Retry Using Exponential Back-Off

When registration or unregistration fails, the app should retry the failed operation.

In the simplest case, if your app attempts to register and GCM is not a fundamental part of the app, the app could simply ignore the error and try to register again the next time it starts. Otherwise, it should retry the previous operation using exponential back-off. In exponential back-off, each time there is a failure, it should wait twice the previous amount of time before trying again.

Unregistration

This section explains when you should unregister in GCM and what happens when you do.

Why you should rarely unregister

You should only need to unregister in rare cases, such as if you want an app to stop receiving messages, or if you suspect that the registration ID has been compromised. In general, once an app has a registration ID, you shouldn't need to change it.

In particular, you should never unregister your app as a mechanism for logout or for switching between users, for the following reasons:

  • A registration ID isn't associated with a particular logged in user. If you unregister and then re-register, GCM may return the same ID or a different ID—there's no guarantee either way.
  • Unregistration may take up to 5 minutes to propagate.
  • After unregistration, re-registration may again take up to 5 minutes to propagate. During this time messages may be rejected due to the state of being unregistered, and after all this, messages may still go to the wrong user.

To make sure that messages go to the intended user:

  • Your app server can maintain a mapping between the current user and the registration ID.
  • The app can then check to ensure that messages it receives match the logged in user.

How unregistration works

A client app can be automatically unregistered after it is uninstalled. However, this process does not happen right away. What happens in this scenario is as follows:

  1. The end user uninstalls the client app.
  2. The 3rd-party app server sends a message to GCM server.
  3. The GCM server sends the message to the GCM client on the device.
  4. The GCM client on the device receives the message and detects that the client app has been uninstalled; the detection details depend on the platform on which the client app is running.
  5. The GCM client on the device informs the GCM server that the client app was uninstalled.
  6. The GCM server marks the registration ID for deletion.
  7. The 3rd-party app server sends a message to GCM.
  8. The GCM returns a NotRegistered error message to the 3rd-party app server.
  9. The 3rd-party app server deletes the registration ID.

Note that it might take a while for the registration ID be completely removed from GCM. Thus it is possible that messages sent during step 7 above gets a valid message ID as response, even though the message will not be delivered to the client app. Eventually, the registration ID will be removed and the server will get a NotRegistered error, without any further action being required from the 3rd-party server (this scenario happens frequently while an app is being developed and tested).