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 & 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