Home | History | Annotate | Download | only in articles
      1 <meta name="doc-family" content="apps">
      2 <h1 id="gcm">Google Cloud Messaging</h1>
      3 
      4 <p>Google Cloud Messaging (GCM) is a service for both Android-powered device and
      5 Chrome instances to send and receive message data from servers.
      6 The <a href="gcm">chrome.gcm API</a> allows the Chrome apps or extensions
      7 to access the GCM service for the signed-in Chrome users.
      8 The service works even if an app or extension isn't currently running.
      9 For example, calendar updates could be pushed
     10 to users even when their calendar app isn't open. </p>
     11 
     12 <p>To use both API and service, you must agree to the <a href="https://developers.google.com/terms/">Google APIs Terms of
     13 Service</a> and <a href="https://developers.google.com/cloud/terms/">Google Cloud Platform Terms
     14 of Service</a>.</p>
     15 
     16 <p>This document describes how to set up and use GCM. For additional information
     17 see the reference documentation for the <a href="gcm">GCM Chrome API</a> and
     18 the <a href="http://developer.android.com/google/gcm/index.html">GCM Service</a>. To get
     19 help with GCM or to give us feedback, please see
     20 <a href="#feedback">Feedback</a>.</p>
     21 
     22 <p class="note"><strong>API Samples</strong>: Want to play with the code? Check out the
     23 <a href="https://github.com/GoogleChrome/chrome-app-samples/tree/master/samples/gcm-notifications">gcm-notifications</a>
     24 sample.</p>
     25 
     26 <h2 id="enable_gcm">Enable GCM</h2>
     27 
     28 <p>To use GCM for your app or extension, do the following:</p>
     29 
     30 <ol>
     31 <li>Upload your app or extension client to the <a href="https://developers.google.com/chrome/web-store/docs/publish">Chrome Web
     32 Store</a>.</li>
     33 <li>A user installs your app or extension.</li>
     34 <li>Your app or extension client requests a registration ID using $(ref:gcm.register)
     35 function and sends this ID to your server together with information
     36 identifying the user. For more details, please see <a href="#obtain_registration_id">Obtain registration
     37 ID</a>.</li>
     38 </ol>
     39 
     40 <h2 id="receive_a_message">Receive a message</h2>
     41 
     42 <p>At a glance, receiving a message works like this:</p>
     43 
     44 <ol>
     45 <li>Your app or extension client should register a handler to receive the
     46 $(ref:gcm.onMessage) event.</li>
     47 <li>When your server sends a message to the user, it specifies all of the
     48 registration IDs that are related to that user and passes the message to the
     49 GCM service.</li>
     50 <li>GCM servers route the message to all instances of Chrome running apps or
     51 extensions with one of the registration IDs.</li>
     52 <li>When the message arrives on the client, Chrome starts the app or extension,
     53 if it is not already running, and calls the registered handler to process the
     54 message.</li>
     55 </ol>
     56 
     57 <p>For more details, please see <a href="#receive_messages">Receive messages</a>.</p>
     58 
     59 <h2 id="send_a_message">Send a message</h2>
     60 
     61 <p>At a glance, sending a message works like this:</p>
     62 
     63 <ol>
     64 <li>Your app or extension generates a unique message ID, so that it is possible
     65 to find out which message failed to be queued or delivered.</li>
     66 <li>Your app or extension calls $(ref:gcm.send) function with an object containing
     67 message ID, destination ID that identifies the server, and data that consist
     68 of a list of key value pairs. In this step you can also provide an optional
     69 time-to-live for the message.</li>
     70 <li>The callback passed to $(ref:gcm.send) function will be called to notify the
     71 result. Your app or extension should check $(ref:runtime.lastError) to find out if
     72 the message has been successfully queued for delivery. Please refer to <a href="#error_reference">Error
     73 reference</a> for possible error codes that could be
     74 returned.</li>
     75 <li>In cases that the queued message could not be delivered to the GCM server,
     76 like network error, a $(ref:gcm.onSendError) event will be fired. Your app or
     77 extension can listen to this event and react to it, e.g. by trying to resend
     78 the message. Please refer to <a href="#error_reference">Error reference</a> for
     79 possible error codes that could be returned.</li>
     80 </ol>
     81 
     82 <p>For more details, please see <a href="#send_messages">Send messages</a>.</p>
     83 
     84 <p class="note"><strong>Display messages in rich notifications format:</strong><br>
     85 GCM and rich notifications API are a natural fit;
     86 Use GCM to send and receive message data; use rich notifications to display
     87 the data in the user's system tray
     88 (see <a href="inform_users">Keep Users Informed</a>).</p>
     89 
     90 <h2 id="set_up_project">Set up project</h2>
     91 
     92 <h3 id="create_google_api_project">Create Google API project</h3>
     93 
     94 <ol>
     95 <li>Login to the <a href="https://cloud.google.com/console/project">Google Developers
     96 Console</a> using the same Google Account that you will use to upload your app or extension.</li>
     97 <li>If you haven't created an API project yet, click <strong>Create Project</strong>.</li>
     98 <li>Supply a project name and click <strong>Create</strong>.</li>
     99 <li>Once the project has been created, a page appears that displays your project
    100 number. For example, <strong>Project Number: 670330094152</strong>.</li>
    101 <li>Copy down your project number. You will use it later on as the GCM sender ID.</li>
    102 </ol>
    103 
    104 <h3 id="enable_the_gcm_service">Enable the GCM service</h3>
    105 
    106 <ol>
    107 <li>In the sidebar on the left, select <strong>APIs &amp; auth</strong>.</li>
    108 <li>In the displayed list of APIs, turn the <strong>Google Cloud Messaging for
    109 Android</strong> toggle to ON.</li>
    110 </ol>
    111 
    112 <h2 id="set_up_chrome_app_or_extension">Set up Chrome App or Extension</h2>
    113 
    114 <h3 id="add_permission_to_manifest">Add permission to manifest</h3>
    115 
    116 <p>To use the gcm service, you must declare the <code>gcm</code> permission in
    117 <code>manifest.json</code>.</p>
    118 
    119 <pre data-filename="manifest.json"><code>
    120 "permissions": [
    121   "gcm", "storage", ...
    122 ]
    123 </code></pre>
    124 
    125 <p>Please note that the <code>storage</code> permission is also provided here because the
    126 sample codes below needs to persist some data via the
    127 <a href="storage">chrome.storage</a> API.</p>
    128 
    129 <h2 id="write_chrome_app_or_extension">Write Chrome App or Extension</h2>
    130 
    131 <h3 id="obtain_registration_id">Obtain registration ID</h3>
    132 
    133 <p>Your app or extension needs to register with GCM servers before it can receive
    134 messages. When an app or extension registers, it receives a registration ID.
    135 This is achieved by calling $(ref:gcm.register) and specifying a list of senders
    136 identified by project numbers from Google Developers Console. Your app or
    137 extension should pass a callback function to verify that the registration was
    138 successful. If successful, the received registration ID should be sent back to
    139 your application server in a secure way, for example, via https. Otherwise, your
    140 app or extension should handle the error identified by
    141 <code>chrome.runtime.lastError</code> and retry later.</p>
    142 
    143 <p>If your app or extension wishes to receive messages from the different senders,
    144 it can call $(ref:gcm.register) again with the new sender list and the new
    145 registration ID will be returned.</p>
    146 
    147 <pre data-filename="background.js"><code>
    148 function registerCallback(registrationId) {
    149   if (chrome.runtime.lastError) {
    150     // When the registration fails, handle the error and retry the
    151     // registration later.
    152     return;
    153   }
    154 
    155   // Send the registration ID to your application server.
    156   sendRegistrationId(function(succeed) {
    157     // Once the registration ID is received by your server,
    158     // set the flag such that register will not be invoked
    159     // next time when the app starts up.
    160     if (succeed)
    161       chrome.storage.local.set({registered: true});
    162   });
    163 }
    164 
    165 function sendRegistrationId(callback) {
    166   // Send the registration ID to your application server
    167   // in a secure way.
    168 }
    169 
    170 chrome.runtime.onStartup.addListener(function() {
    171   chrome.storage.local.get("registered", function(result) {
    172     // If already registered, bail out.
    173     if (result["registered"])
    174       return;
    175 
    176     // Up to 100 senders are allowed.
    177     var senderIds = ["Your-Sender-ID"];
    178     chrome.gcm.register(senderIds, registerCallback);
    179   });
    180 });
    181 </code></pre>
    182 
    183 <p>If your app or extension is installed in different profiles and/or in different
    184 Chrome instances, each of them will receive a different registration ID.</p>
    185 
    186 <p>Your app or extension could call $(ref:gcm.unregister) to revoke the registration ID.
    187 The unregistration should only be done in rare cases, such as if your app or
    188 extension does not want to receive further messages, or the registration ID is
    189 suspected to be compromised.</p>
    190 
    191 <pre data-filename="background.js"><code>
    192 function unregisterCallback() {
    193   if (chrome.runtime.lastError) {
    194     // When the unregistration fails, handle the error and retry
    195     // the unregistration later.
    196     return;
    197   }
    198 }
    199 
    200 chrome.gcm.unregister(unregisterCallback);
    201 </code></pre>
    202 
    203 <p>Your app or extension is automatically unregistered from the GCM service when a
    204 user uninstalls it.</p>
    205 
    206 <h3 id="receive_messages">Receive messages</h3>
    207 
    208 <p>When your server sends a message to the user, it specifies all of the
    209 registration IDs that are related to that user and passes the message to the GCM
    210 service. GCM servers route the message to all instances of Chrome running apps
    211 or extensions with one of the registration IDs. If your app or extension has
    212 been installed in more than one profiles in a single Chrome instance, all of
    213 them can receive messages independently based on their unique registration IDs.</p>
    214 
    215 <p>Messages from the server are delivered via the $(ref:gcm.onMessage) event. Your app
    216 or extension must register a handler to receive this event.</p>
    217 
    218 <pre data-filename="background.js"><code>
    219 chrome.gcm.onMessage.addListener(function(message) {
    220   // A message is an object with a data property that
    221   // consists of key-value pairs.
    222 });
    223 </code></pre>
    224 
    225 <p>As long as Chrome is running, even if the extension or app is not running, it is
    226 woken up to deliver a message.</p>
    227 
    228 <h3 id="send_messages">Send messages</h3>
    229 
    230 <p>To send messages upstream, your app or extension should call $(ref:gcm.send) with an
    231 object containing:</p>
    232 
    233 <ul>
    234 <li>Message ID that identifies the message when it fails to be queued or
    235 delivered. The message ID can be any kind of string. However, it is
    236 recommended to stay unique across the lifetime of your app or extension, even
    237 after it restarts. If you use the same message ID, there may be a chance that
    238 the previous message gets overridden. If an auto-increment counter is used to
    239 create the message ID, your app or extension should persist the counter value
    240 via <a href="storage">chrome.storage</a> API and restore it when the app
    241 reloads.</li>
    242 <li>Destination ID that identifies the server. This is the project number from the
    243 Google Developers Console plus the suffix "@gcm.googleapis.com".</li>
    244 <li>Data that consist of a list of string-to-string key value pairs (up to 4KB
    245 total).</li>
    246 <li>Time-to-live (TTL, optional). This property value must be a duration from 0 to
    247 2,419,200 seconds (4 weeks) and it corresponds to the maximum period of time
    248 for which GCM will store and try to deliver the message. If this property is
    249 not set, it is default to the maximum value. When a TTL is set to 0, GCM will
    250 try to deliver the message immediately. If the immediate effort fails, the
    251 message will be discarded.</li>
    252 </ul>
    253 
    254 <p>When the callback passed in $(ref:gcm.send) is called without runtime error, it does
    255 not mean that the message was already delivered to the GCM server. Rather, it
    256 means that it was queued for delivery. If the message fails to reach the
    257 destination within the specified TTL period, for example due to network error,
    258 the $(ref:gcm.onSendError) will be fired.</p>
    259 
    260 <pre data-filename="background.js"><code>
    261 // Substitute your own sender ID here. This is the project
    262 // number you got from the Google Developers Console.
    263 var senderId = "Your-Sender-ID";
    264 
    265 // Make the message ID unique across the lifetime of your app.
    266 // One way to achieve this is to use the auto-increment counter
    267 // that is persisted to local storage.
    268 
    269 // Message ID is saved to and restored from local storage.
    270 var messageId = 0;
    271 chrome.storage.local.get("messageId", function(result) {
    272   if (chrome.runtime.lastError)
    273     return;
    274   messageId = parseInt(result["messageId"]);
    275   if (isNaN(messageId))
    276     messageId = 0;
    277 });
    278 
    279 // Sets up an event listener for send error.
    280 chrome.gcm.onSendError.addListener(sendError);
    281 
    282 // Returns a new ID to identify the message.
    283 function getMessageId() {
    284   messageId++;
    285   chrome.storage.local.set({messageId: messageId});
    286   return messageId.toString();
    287 }
    288 
    289 function sendMessage() {
    290   var message = {
    291     messageId: getMessageId(),
    292     destinationId: senderId + "@gcm.googleapis.com",
    293     timeToLive: 86400,    // 1 day
    294     data: {
    295       "key1": "value1",
    296       "key2": "value2"
    297     }
    298   };
    299   chrome.gcm.send(message, function(messageId) {
    300     if (chrome.runtime.lastError) {
    301       // Some error occurred. Fail gracefully or try to send
    302       // again.
    303       return;
    304     }
    305 
    306     // The message has been accepted for delivery. If the message
    307     // can not reach the destination, onSendError event will be
    308     // fired.
    309   });
    310 }
    311 
    312 function sendError(error) {
    313   console.log("Message " + error.messageId +
    314       " failed to be sent: " + error.errorMessage);
    315 }
    316 </code></pre>
    317 
    318 <h3 id="messages_deleted_event">Messages deleted event</h3>
    319 
    320 <p>GCM will store up to 100 non-collapsible messages. After that, all messages are
    321 discarded from GCM, and an event $(ref:gcm.onMessagesDeleted) will be fired, which
    322 tells the client that it falls behind. Your app or extension should respond by
    323 syncing with your application server to recover the discarded messages.</p>
    324 
    325 <pre data-filename="background.js"><code>
    326 chrome.gcm.onMessagesDeleted.addListener(messagesDeleted);
    327 
    328 function messagesDeleted() {
    329   // All messages have been discarded from GCM. Sync with
    330   // your application server to recover from the situation.
    331 }
    332 </code></pre>
    333 
    334 <h3 id="collapsible_messages">Collapsible messages</h3>
    335 
    336 <p>GCM messages are often a tickle, telling the app or extension to contact the
    337 server for fresh data. In GCM, it's possible to create collapsible messages for
    338 this situation, wherein new messages replace older ones. When a collapse key is
    339 provided and multiple messages are queued up in the GCM servers for the same
    340 user, only the last one with any given collapse key is delivered to your app or
    341 extension. As a result the <code>message</code> object passed to the $(ref:gcm.onMessage) event
    342 will contain a <code>collapseKey</code>field. For more details about sending collapsible
    343 messages, please refer to <a href="http://developer.android.com/google/gcm/adv.html#collapsible">GCM Advance
    344 Topics</a>.</p>
    345 
    346 <h2 id="publish_your_app">Publish your app</h2>
    347 
    348 <p>To use the GCM service, you must publish your app in the <a href="https://developers.google.com/chrome/web-store/docs/publish">Chrome Web
    349 Store</a>.</p>
    350 
    351 <h2 id="error_reference">Error reference</h2>
    352 
    353 <p>An error could occur when a gcm API function is called. Your app or extension
    354 should check $(ref:runtime.lastError) for more information in your callback. The
    355 error code will also be passed as a parameter to $(ref:gcm.onSendError) event.</p>
    356 
    357 <p>Here's a brief summary of the gcm errors:</p>
    358 
    359 <ul>
    360 <li><strong>Function was called with invalid parameters</strong>: this could happen when gcm
    361 functions are called with bad parameters.</li>
    362 <li><strong>Profile was not signed in</strong>: this could happen when gcm functions are called
    363 from a profile that was not signed in.</li>
    364 <li><strong>Asynchronous operation is pending</strong>: this could happen when certain gcm
    365 function is called again without waiting for the callback passed in previous
    366 function to be called.</li>
    367 <li><strong>Network error occurred</strong>: this could happen when GCM server fails to reach
    368 due to network problem, like losing Internet connection.</li>
    369 <li><strong>Server error occurred</strong>: this could happen when GCM server fails to reach
    370 due to server problem, like server busy.</li>
    371 <li><strong>Time-to-live exceeded</strong>: this could happen when a message could not be
    372 delivered within the specific time-to-live period.</li>
    373 <li><strong>Unknown error occurred</strong>: this could happen due to any other internal
    374 errors.</li>
    375 </ul>
    376 
    377 <h2 id="feedback">Feedback</h2>
    378 
    379 <p>You can provide feedback about Google Cloud Messaging and the
    380 <a href="gcm">chrome.gcm API</a> through
    381 the Google Group <a href="https://groups.google.com/forum/#!forum/gcm-for-chrome-feedback">GCM for Chrome
    382 Feedback</a>.
    383 Use this group to ask for help, file bug reports, and request features.</p>
    384