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