As of April 10, 2018, Google has deprecated GCM. The GCM server and client APIs are deprecated and will be removed as soon as May 29, 2019. Migrate GCM apps to Firebase Cloud Messaging (FCM), which inherits the reliable and scalable GCM infrastructure, plus many new features. See the migration guide to learn more.

Implementing GCM Client on Chrome

Google Cloud Messaging provides messaging services for Chrome in two ways:

  • Chrome apps and extensions can access the GCM service directly through chrome.gcm API.
  • Websites in Chrome can implement push messaging through service workers and web app manifests.

The rest of this page describes the GCM support for Chrome apps and extensions only; for website support, see the push messaging codelab.

For Chrome apps and extensions, GCM enables Chrome instances to send and receive message data from servers. The chrome.gcm API allows the Chrome apps or extensions to access the GCM service. The service works even if an app or extension isn't currently running. For example, calendar updates could be pushed to users even when their calendar app isn't open.

To use both API and service, you must agree to the Google APIs Terms of Service and Google Cloud Platform Terms of Service.

A full GCM implementation requires both a client implementation and a server implementation. For more information about implementing the server side, see About GCM Connection Server.

Create an API Project and credentials

New GCM projects must generate required security credentials by creating an API project in the Firebase console.

  1. In the Firebase console, select Create New Project.
  2. Supply a project name and click Create Project.
  3. Select the gear icon next to your project name at top left, and select Project Settings.
  4. Select the Cloud Messaging tab. You can find your Server key and sender ID in this page.

Set up Chrome App or Extension

Add permission to manifest

To use the gcm service, you must declare the gcm permission in manifest.json.

"permissions": [
  "gcm", ... // Other permissions, like "storage"

Please note that running sample code below requires the storage permission as well in order to persist some data via the API.

Write Chrome App or Extension

Obtain GCM registration token

Your app or extension needs to register with GCM connection servers before it can receive messages. This is achieved by calling chrome.gcm.register and passing a list of senders identified by project numbers from Google Developers Console. Your app or extension should pass a callback function to verify if the registration succeeded or not, by checking whether the error is set on chrome.runtime.lastError property. If the registration is successful, an app or extension receives a registration token, which should be sent back to your application server in a secure way, for example, via https. Otherwise, your app or extension should handle the error identified by chrome.runtime.lastError and retry later.

If your app or extension wishes to receive messages from the different senders, it can call chrome.gcm.register again with the new sender list and the new registration token will be returned.

function registerCallback(registrationId) {
  if (chrome.runtime.lastError) {
    // When the registration fails, handle the error and retry the
    // registration later.

  // Send the registration token to your application server.
  sendRegistrationId(function(succeed) {
    // Once the registration token is received by your server,
    // set the flag such that register will not be invoked
    // next time when the app starts up.
    if (succeed){registered: true});

function sendRegistrationId(callback) {
  // Send the registration token to your application server
  // in a secure way.

chrome.runtime.onStartup.addListener(function() {"registered", function(result) {
    // If already registered, bail out.
    if (result["registered"])

    // Up to 100 senders are allowed.
    var senderIds = ["Your-Sender-ID"];
    chrome.gcm.register(senderIds, registerCallback);

If your app or extension is installed in different profiles and/or in different Chrome instances, each of them will receive a different registration token.

Your app or extension could call gcm.unregister to revoke the registration token. The unregistration should only be done in rare cases, such as if your app or extension does not want to receive further messages, or the registration token is suspected to be compromised.

function unregisterCallback() {
  if (chrome.runtime.lastError) {
    // When the unregistration fails, handle the error and retry
    // the unregistration later.


Your app or extension is automatically unregistered from the GCM service when a user uninstalls it.

Receive downstream messages

When your server wants to send a message to the user, it needs to connect to a GCM connection server in one of two ways as described in About GCM Connection Server. The message specifies all of the registration tokens that are related to that user. When the GCM connection server receives the message, it routes the message to all instances of Chrome running apps or extensions with one of the registration IDs. If your app or extension has been installed in more than one profiles in a single Chrome instance, all of them can receive messages independently based on their unique registration tokens.

Messages from the server are delivered via the chrome.gcm.onMessage event. Your app or extension must register a handler to receive this event.

chrome.gcm.onMessage.addListener(function(message) {
  // A message is an object with a data property that
  // consists of key-value pairs.

As long as Chrome is running, even if the extension or app is not running, it is woken up to deliver a message.

Send upstream messages

In addition to delivering push messages from your server to the client, the GCM supports sending upstream messages from the client to your server. Your server should be set up to connect to GCM Cloud Connection Server as described in the Implementing an XMPP Connection Server document.

To send messages upstream, your app or extension should call chrome.gcm.send with an object containing:

  • Message ID that identifies the message when it fails to be queued or delivered. The message ID can be any kind of string. However, it is recommended to stay unique across the lifetime of your app or extension, even after it restarts. If you use the same message ID, there may be a chance that the previous message gets overridden. If an auto-increment counter is used to create the message ID, your app or extension should persist the counter value via API and restore it when the app reloads.
  • Destination ID that identifies the server. This is the Sender ID plus the suffix
  • Data that consist of a list of string-to-string key value pairs (up to 4KB total).
  • Time-to-live (TTL, optional). This property value must be a duration from 0 to 86,400 seconds (1 day) and it corresponds to the maximum period of time for which GCM will store and try to deliver the message. If this property is not set, it is default to the maximum value. When a TTL is set to 0, GCM will try to deliver the message immediately. If the immediate effort fails, the message will be discarded.

When the callback passed in chrome.gcm.send is called without runtime error, it does not mean that the message was already delivered to the GCM connection server. Rather, it means that it was queued for delivery. Your app or extension should check and handle chrome.runtime.lastError. Please refer to Error reference for possible error codes that could be returned.

If the message fails to reach the destination within the specified TTL period, for example due to network error, the chrome.gcm.onSendError will be fired. Your app or extension can listen to this event and react to it, e.g. by trying to resend the message. Please refer to Error reference for possible error codes that could be returned.

// Substitute your own sender ID here.
var senderId = "Your-Sender-ID";

// Make the message ID unique across the lifetime of your app.
// One way to achieve this is to use the auto-increment counter
// that is persisted to local storage.

// Message ID is saved to and restored from local storage.
var messageId = 0;"messageId", function(result) {
  if (chrome.runtime.lastError)
  messageId = parseInt(result["messageId"]);
  if (isNaN(messageId))
    messageId = 0;

// Sets up an event listener for send error.

// Returns a new ID to identify the message.
function getMessageId() {
  messageId++;{messageId: messageId});
  return messageId.toString();

function sendMessage() {
  var message = {
    messageId: getMessageId(),
    destinationId: senderId + "",
    timeToLive: 86400,    // 1 day
    data: {
      "key1": "value1",
      "key2": "value2"
  chrome.gcm.send(message, function(messageId) {
    if (chrome.runtime.lastError) {
      // Some error occurred. Fail gracefully or try to send
      // again.

    // The message has been accepted for delivery. If the message
    // can not reach the destination, onSendError event will be
    // fired.

function sendError(error) {
  console.log("Message " + error.messageId +
      " failed to be sent: " + error.errorMessage);

Advanced Topics

Messages deleted event

GCM will store up to 100 non-collapsible messages that are sent from your server to your client. After that, all messages are discarded from GCM, and an event chrome.gcm.onMessagesDeleted will be fired, which tells the client that it falls behind. Your app or extension should respond by syncing with your application server to recover the discarded messages.


function messagesDeleted() {
  // All messages have been discarded from GCM. Sync with
  // your application server to recover from the situation.

Collapsible messages

GCM messages are often a tickle, telling the app or extension to contact the server for fresh data. In GCM, it's possible to create collapsible messages for this situation, wherein new messages replace older ones. When a collapse key is provided and multiple messages are queued up in the GCM connection servers for the same user, only the last one with any given collapse key is delivered to your app or extension. As a result the message object passed to the chrome.gcm.onMessage event will contain a collapseKeyfield.

Error reference

An error could occur when a gcm API function is called. Your app or extension should check chrome.runtime.lastError for more information in your callback. The error code will also be passed as a parameter to chrome.gcm.onSendError event.

Here's a brief summary of the gcm errors:

  • Function was called with invalid parameters: this could happen when gcm functions are called with bad parameters.
  • Asynchronous operation is pending: this could happen when certain gcm function is called again without waiting for the callback passed in previous function to be called.
  • Network error occurred: this could happen when GCM connection server fails to reach due to network problem, like losing Internet connection.
  • Server error occurred: this could happen when GCM connection server fails to reach due to server problem, like server busy.
  • Time-to-live exceeded: this could happen when a message could not be delivered within the specific time-to-live period.
  • Unknown error occurred: this could happen due to any other internal errors.

Send feedback about...

Cloud Messaging
Cloud Messaging