• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
5Chrome instances to send and receive message data from servers. <a href="gcm">GCM Chrome
6API</a> allows the Chrome apps or extensions to access the GCM
7service for the signed-in Chrome users. The service works even if an app or
8extension isn't currently running. For example, calendar updates could be pushed
9to 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
12Service</a> and <a href="https://developers.google.com/cloud/terms/">Google Cloud Platform Terms
13of Service</a>.</p>
14
15<p>This document describes how to set up and use GCM. For additional information
16see the reference documentation for the <a href="gcm">GCM Chrome API</a> and
17the <a href="http://developer.android.com/google/gcm/index.html">GCM Service</a>. To get
18help 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
22users 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/gcm-notifications">gcm-notifications</a>
26sample.</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
34Store</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)
37function and sends this ID to your server together with information
38identifying the user. For more details, please see <a href="#obtain_registration_id">Obtain registration
39ID</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
50registration IDs that are related to that user and passes the message to the
51GCM service.</li>
52<li>GCM servers route the message to all instances of Chrome running apps or
53extensions with one of the registration IDs.</li>
54<li>When the message arrives on the client, Chrome starts the app or extension,
55if it is not already running, and calls the registered handler to process the
56message.</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
67to 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
69message ID, destination ID that identifies the server, and data that consist
70of a list of key value pairs. In this step you can also provide an optional
71time-to-live for the message.</li>
72<li>The callback passed to $(ref:gcm.send) function will be called to notify the
73result. Your app or extension should check $(ref:runtime.lastError) to find out if
74the message has been successfully queued for delivery. Please refer to <a href="#error_reference">Error
75reference</a> for possible error codes that could be
76returned.</li>
77<li>In cases that the queued message could not be delivered to the GCM server,
78like network error, a $(ref:gcm.onSendError) event will be fired. Your app or
79extension can listen to this event and react to it, e.g. by trying to resend
80the message. Please refer to <a href="#error_reference">Error reference</a> for
81possible 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
92Console</a> using the same Google <br>
93Account 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
97number. 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
106Android</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
123sample 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
131messages. When an app or extension registers, it receives a registration ID.
132This is achieved by calling $(ref:gcm.register) and specifying a list of senders
133identified by project numbers from Google Developers Console. Your app or
134extension should pass a callback function to verify that the registration was
135successful. If successful, the received registration ID should be sent back to
136your application server in a secure way, for example, via https. Otherwise, your
137app 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,
141it can call $(ref:gcm.register) again with the new sender list and the new
142registration ID will be returned.</p>
143
144<pre data-filename="background.js"><code>
145function 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
162function sendRegistrationId(callback) {
163  // Send the registration ID to your application server
164  // in a secure way.
165}
166
167chrome.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
181Chrome 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.
184The unregistration should only be done in rare cases, such as if your app or
185extension does not want to receive further messages, or the registration ID is
186suspected to be compromised.</p>
187
188<pre data-filename="background.js"><code>
189function 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
197chrome.gcm.unregister(unregisterCallback);
198</code></pre>
199
200<p>Your app or extension is automatically unregistered from the GCM service when a
201user 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
206registration IDs that are related to that user and passes the message to the GCM
207service. GCM servers route the message to all instances of Chrome running apps
208or extensions with one of the registration IDs. If your app or extension has
209been installed in more than one profiles in a single Chrome instance, all of
210them 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
213or extension must register a handler to receive this event.</p>
214
215<pre data-filename="background.js"><code>
216chrome.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
223woken 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
228object containing:</p>
229
230<ul>
231<li>Message ID that identifies the message when it fails to be queued or
232delivered. The message ID can be any kind of string. However, it is
233recommended to stay unique across the lifetime of your app or extension, even
234after it restarts. If you use the same message ID, there may be a chance that
235the previous message gets overridden. If an auto-increment counter is used to
236create the message ID, your app or extension should persist the counter value
237via <a href="storage">chrome.storage</a> API and restore it when the app
238reloads.</li>
239<li>Destination ID that identifies the server. This is the project number from the
240Google 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
242total).</li>
243<li>Time-to-live (TTL, optional). This property value must be a duration from 0 to
2442,419,200 seconds (4 weeks) and it corresponds to the maximum period of time
245for which GCM will store and try to deliver the message. If this property is
246not set, it is default to the maximum value. When a TTL is set to 0, GCM will
247try to deliver the message immediately. If the immediate effort fails, the
248message will be discarded.</li>
249</ul>
250
251<p>When the callback passed in $(ref:gcm.send) is called without runtime error, it does
252not mean that the message was already delivered to the GCM server. Rather, it
253means that it was queued for delivery. If the message fails to reach the
254destination within the specified TTL period, for example due to network error,
255the $(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.
260var 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.
267var messageId = 0;
268chrome.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.
277chrome.gcm.onSendError.addListener(sendError);
278
279// Returns a new ID to identify the message.
280function getMessageId() {
281  messageId++;
282  chrome.storage.local.set({messageId: messageId});
283  return messageId.toString();
284}
285
286function 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
309function 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
318discarded from GCM, and an event $(ref:gcm.onMessagesDeleted) will be fired, which
319tells the client that it falls behind. Your app or extension should respond by
320syncing with your application server to recover the discarded messages.</p>
321
322<pre data-filename="background.js"><code>
323chrome.gcm.onMessagesDeleted.addListener(messagesDeleted);
324
325function 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
334server for fresh data. In GCM, it's possible to create collapsible messages for
335this situation, wherein new messages replace older ones. When a collapse key is
336provided and multiple messages are queued up in the GCM servers for the same
337user, only the last one with any given collapse key is delivered to your app or
338extension. As a result the <code>message</code> object passed to the $(ref:gcm.onMessage) event
339will contain a <code>collapseKey</code>field. For more details about sending collapsible
340messages, please refer to <a href="http://developer.android.com/google/gcm/adv.html#collapsible">GCM Advance
341Topics</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
346Store</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
351should check $(ref:runtime.lastError) for more information in your callback. The
352error 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
358functions are called with bad parameters.</li>
359<li><strong>Profile was not signed in</strong>: this could happen when gcm functions are called
360from a profile that was not signed in.</li>
361<li><strong>Asynchronous operation is pending</strong>: this could happen when certain gcm
362function is called again without waiting for the callback passed in previous
363function to be called.</li>
364<li><strong>Network error occurred</strong>: this could happen when GCM server fails to reach
365due to network problem, like losing Internet connection.</li>
366<li><strong>Server error occurred</strong>: this could happen when GCM server fails to reach
367due to server problem, like server busy.</li>
368<li><strong>Time-to-live exceeded</strong>: this could happen when a message could not be
369delivered within the specific time-to-live period.</li>
370<li><strong>Unknown error occurred</strong>: this could happen due to any other internal
371errors.</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
377the Google Group <a href="https://groups.google.com/forum/#!forum/gcm-for-chrome-feedback">GCM for Chrome
378Feedback</a>.
379Use this group to ask for help, file bug reports, and request features.</p>
380