| OLD | NEW |
| (Empty) |
| 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">GC
M 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://developer
s.google.com/terms/">Google APIs Terms of | |
| 12 Service</a> and <a href="https://developers.google.com/cloud/terms/">Google Clou
d 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 Chro
me | |
| 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.googl
e.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.regi
ster) | |
| 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 containi
ng | |
| 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 Devel
opers | |
| 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</str
ong>.</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 & 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 be
cause 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 receiv
e | |
| 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 sender
s, | |
| 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 differe
nt | |
| 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 registra
tion 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. Yo
ur 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 t
he | |
| 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 a
re | |
| 318 discarded from GCM, and an event $(ref:gcm.onMessagesDeleted) will be fired, whi
ch | |
| 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.o
nMessage) event | |
| 339 will contain a <code>collapseKey</code>field. For more details about sending col
lapsible | |
| 340 messages, please refer to <a href="http://developer.android.com/google/gcm/adv.h
tml#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://dev
elopers.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 hap
pen when gcm | |
| 358 functions are called with bad parameters.</li> | |
| 359 <li><strong>Profile was not signed in</strong>: this could happen when gcm funct
ions are called | |
| 360 from a profile that was not signed in.</li> | |
| 361 <li><strong>Asynchronous operation is pending</strong>: this could happen when c
ertain 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 f
ails 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 fa
ils 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 cou
ld 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> | |
| OLD | NEW |