OSDN Git Service

docs: Fix notification api guide issues (7461154, 12765600)
[android-x86/frameworks-base.git] / docs / html / google / gcm / adv.jd
1 page.title=GCM Advanced Topics
2 @jd:body
3
4 <div id="qv-wrapper">
5 <div id="qv">
6
7 <h2>Quickview</h2>
8
9 <ul>
10 <li>Learn more about GCM advanced features.</li>
11 </ul>
12
13
14 <h2>In this document</h2>
15
16 <ol>
17 <li><a href="#lifetime">Lifetime of a Message</a></li>
18 <li><a href="#throttling">Throttling</a></li>
19 <li><a href="#reg-state">Keeping the Registration State in Sync</a>
20   <ol>
21     <li><a href="#canonical">Canonical IDs</a></li>
22   </ol>
23 </li>
24 <li><a href="#retry">Automatic Retry Using Exponential Back-Off</a></li>
25 <li><a href="#unreg">Unregistration</a>
26   <ol>
27     <li><a href="#unreg-why">Why you should rarely unregister</a></li>
28     <li><a href="#unreg-how">How unregistration works</a></li>
29   </ol>
30 </li>
31 <li><a href="#collapsible">Send-to-Sync vs. Messages with Payload</a>
32   <ol>
33     <li><a href="#s2s">Send-to-sync messages</a></li>
34     <li><a href="#payload">Messages with payload</a></li>
35 <li><a href="#which">Which should I use?</a></li>
36     </ol>
37 </li>
38 <li><a href="#ttl">Setting an Expiration Date for a Message</a> </li>
39 <li><a href="#throttling"></a><a href="#multi-senders">Receiving Messages from
40 Multiple Senders</a></li>
41 </ol>
42
43 </div>
44 </div>
45 <p>This document covers advanced topics for GCM.</p>
46
47
48
49
50 <h2 id="msg-lifetime">Lifetime of a Message</h2>
51 <p>When a 3rd-party server posts a message to GCM and receives a message ID back,
52 it does not mean that the message was already delivered to the device. Rather, it
53 means that it was accepted for delivery. What happens to the message after it is
54 accepted depends on many factors.</p>
55
56 <p>In the best-case scenario, if the device is connected to GCM, the screen is on,
57 and there are no throttling restrictions (see <a href="#throttling">Throttling</a>),
58 the message will be delivered right away.</p>
59
60 <p>If the device is connected but idle, the message will still be
61 delivered right away unless the <code>delay_while_idle</code> flag is set to true.
62 Otherwise, it will be stored in the GCM servers until the device is awake. And
63 that's where the <code>collapse_key</code> flag plays a role: if there is already
64 a message with the same collapse key (and registration ID) stored and waiting for
65 delivery, the old message will be discarded and the new message will take its place
66 (that is, the old message will be collapsed by the new one). However, if the collapse
67 key is not set, both the new and old messages are stored for future delivery.
68 Collapsible messages are also called <a href="#s2s">send-to-sync messages</a>.</p>
69
70 <p class="note"><strong>Note:</strong> There is a limit on how many messages can
71 be stored without collapsing. That limit is currently 100. If the limit is reached,
72 all stored messages are discarded. Then when the device is back online, it receives
73 a special message indicating that the limit was reached. The application can then
74 handle the situation properly, typically by requesting a full sync.
75 <br><br>
76 Likewise, there is a limit on how many <code>collapse_key</code>s you can have for
77 a particular device. GCM allows a maximum of 4 different collapse keys to be used
78 by the GCM server per device
79 any given time. In other words, the GCM server can simultaneously store 4 different
80 send-to-sync messages, each with a different collapse key. If you exceed this number
81 GCM will only keep 4 collapse keys, with no guarantees about which ones they will be.
82 See <a href="#s2s">Send-to-sync messages</a> for more information.
83 </p>
84
85 <p>If the device is not connected to GCM, the message will be stored until a
86 connection is established (again respecting the collapse key rules). When a connection
87 is established, GCM will deliver all pending messages to the device, regardless of
88 the <code>delay_while_idle</code> flag. If the device never gets connected again
89 (for instance, if it was factory reset), the message will eventually time out and
90 be discarded from GCM storage. The default timeout is 4 weeks, unless the
91 <code>time_to_live</code> flag is set.</p>
92
93 <p>Finally, when GCM attempts to deliver a message to the device and the
94 application was uninstalled, GCM will discard that message right away and
95 invalidate the registration ID. Future attempts to send a message to that device
96 will get a <code>NotRegistered</code> error. See <a href="#unreg">
97 How Unregistration Works</a> for more information.</p>
98 <p>Although is not possible to track the status of each individual message, the
99 Google Cloud Console stats are broken down by messages sent to device, messages
100 collapsed, and messages waiting for delivery.</p>
101
102 <h2 id="throttling">Throttling</h2>
103 <p>To prevent abuse (such as sending a flood of messages to a device) and
104 to optimize for the overall network efficiency and battery life of
105 devices, GCM implements throttling of messages using a token bucket
106 scheme. Messages are throttled on a per application and per <a href="#collapsible">collapse
107 key</a> basis (including non-collapsible messages). Each application
108 collapse key is granted some initial tokens, and new tokens are granted
109 periodically therefter. Each token is valid for a single message sent to
110 the device. If an application collapse key exhausts its supply of
111 available tokens, new messages are buffered in a pending queue until
112 new tokens become available at the time of the periodic grant. Thus
113 throttling in between periodic grant intervals may add to the latency
114 of message delivery for an application collapse key that sends a large
115 number of messages within a short period of time. Messages in the pending
116 queue of an application collapse key may be delivered before the time
117 of the next periodic grant, if they are piggybacked with messages
118 belonging to a non-throttled category by GCM for network and battery
119 efficiency reasons.</p>
120
121 <h2 id="reg-state">Keeping the Registration State in Sync</h2>
122 <p>Whenever the application registers as described in
123 <a href="{@docRoot}google/gcm/client.html">Implementing GCM Client</a>,
124 it should save the registration ID for future use, pass it to the
125 3rd-party server to complete the registration, and keep track of
126 whether the server completed the registration. If the server fails
127 to complete the registration, it should try again or unregister from GCM.</p>
128
129 <p>There are also two other scenarios that require special care:</p>
130 <ul>
131   <li>Application update</li>
132   <li>Backup and restore
133   </li>
134 </ul>
135 <p>When an application is updated, it should invalidate its existing registration
136 ID, as it is not guaranteed to work with the new version.  Because there is no
137 lifecycle method called when the application is updated, the best way to achieve
138 this validation is by storing the current application version when a registration
139 ID is stored. Then when the application is started, compare the stored value with
140 the current application version. If they do not match, invalidate the stored data
141 and start the registration process again.</p>
142
143 <p>Similarly, you should not save the registration ID when an application is
144 backed up. This is because the registration ID could become invalid by the time
145 the application is restored, which would put the application in an invalid state
146 (that is, the application thinks it is registered, but the server and GCM do not
147 store that registration ID anymore&mdash;thus the application will not get more
148 messages).</p>
149 <h3 id="canonical">Canonical IDs</h3>
150 <p>On the server side, as long as the application is behaving well, everything
151 should work normally. However, if a bug in the application triggers multiple
152 registrations for the same device, it can be hard to reconcile state and you might
153 end up with duplicate messages.</p>
154 <p>GCM provides a facility called &quot;canonical registration IDs&quot; to easily
155 recover from these situations. A canonical registration ID is defined to be the ID
156 of the last registration requested by your application. This is the ID that the
157 server should use when sending messages to the device.</p>
158 <p>If later on you try to send a message using a different registration ID, GCM
159 will process the request as usual, but it will include the canonical registration
160 ID in the <code>registration_id</code> field of the response. Make sure to replace
161 the registration ID stored in your server with this canonical ID, as eventually
162 the ID you're using will stop working.</p>
163
164 <h2 id="retry">Automatic Retry Using Exponential Back-Off</h2>
165
166 <p>When registration or unregistration fails, the app should retry the failed operation.</p>
167 <p>In the simplest case, if your application attempts to register and GCM is not a
168 fundamental part of the application, the application could simply ignore the error
169 and try to register again the next time it starts. Otherwise, it should retry the
170 previous operation using exponential back-off. In exponential back-off, each time
171 there is a failure, it should wait twice the previous amount of time before trying
172 again. If the register (or unregister) operation was synchronous, it could be retried
173 in a simple loop. However, since it is asynchronous, the best approach is to schedule
174 a {@link android.app.PendingIntent} to retry the operation.
175
176 <h2 id="unreg">Unregistration</h2>
177
178 <p>This section explains when you should unregister in GCM and what happens
179 when you do.</p>
180
181 <h3 id="unreg-why">Why you should rarely unregister</h3>
182
183 <p>A registration ID (regID) represents a particular Android application running
184 on a particular device. You should only need to unregister in rare cases, such as
185 if you want an app to stop receiving messages, or if you suspect that the regID has
186 been compromised. In general, though, once an app has a regID, you shouldn't need
187 to change it.</p>
188
189 <p>In particular, you should never unregister your app as a mechanism for
190 logout or for switching between users, for the following reasons:</p>
191
192 <ul>
193   <li>A regID maps an app to a device. It isn't associated with a particular
194   logged in user. If you unregister and then re-register, GCM may return the same
195   ID or a different ID&mdash;there's no guarantee either way.</li>
196
197   <li>Unregistration may take up to 5 minutes to propagate.</li>
198   <li>After unregistration, re-registration may again take up to 5 minutes to
199 propagate. During this time messages may be rejected due to the state of being
200 unregistered, and after all this, messages may still go to the wrong user.</li>
201 </ul>
202
203
204 <p>The solution is to manage your own mapping between users, the regID, and
205 individual messages:</p>
206
207 <ul>
208   <li>Your app server should maintain a mapping between the current user
209 and the regID. This should include information about which user is supposed to
210 receive a particular message.</li>
211   <li>The app running on the device should check to ensure that messages it
212 receives match the logged in user.</li>
213 </ul>
214
215
216 <h3 id="unreg-how">How unregistration works</h3>
217
218 <p>An application can be automatically unregistered after it is uninstalled from
219 the device. However, this process does not happens right away, as Android does not
220 provide an uninstall callback. What happens in this scenario is as follows:</p>
221 <ol>
222   <li>The end user uninstalls the application.</li>
223   <li>The 3rd-party server sends a message to GCM server.</li>
224   <li>The GCM server sends the message to the device.</li>
225   <li>The GCM client receives the message and queries Package Manager about
226 whether there are broadcast receivers configured to receive it, which returns
227 <code>false</code>.
228 </li>
229   <li>The GCM client informs the GCM server that the application was uninstalled.</li>
230   <li>The GCM server marks the registration ID for deletion.</li>
231   <li>The 3rd-party server sends a message to  GCM.</li>
232   <li>The GCM returns a <code>NotRegistered</code> error message to the 3rd-party server.</li>
233   <li>The 3rd-party deletes the registration ID.
234   </li>
235 </ol>
236
237 <p class ="note"><strong>Note:</strong> The GCM client is the Google Cloud
238 Messaging framework present on the device.</p>
239
240 <p>Note that it might take a while for the registration ID be completely removed
241 from GCM. Thus it is possible that messages sent during step 7 above gets a valid
242 message ID as response, even though the message will not be delivered to the device.
243 Eventually, the registration ID will be removed and the server will get a
244 <code>NotRegistered</code> error, without any further action being required from
245 the 3rd-party server (this scenario happens frequently while an application is
246 being developed and tested).</p>
247
248 <h2 id="collapsible">Send-to-Sync  vs. Messages with Payload</h2>
249
250 <p>Every message sent in GCM has the following characteristics:</p>
251 <ul>
252   <li>It has a payload limit of 4096 bytes.</li>
253   <li>By default, it is stored by GCM for 4 weeks.</li>
254 </ul>
255
256 <p>But despite these similarities, messages can behave very differently depending
257 on their particular settings. One major distinction between messages is whether
258 they are collapsed (where each new message replaces the preceding message) or not
259 collapsed (where each individual message is delivered). Every message sent in GCM
260 is either a &quot;send-to-sync&quot; (collapsible) message or a &quot;message with
261 payload&quot; (non-collapsible message). These concepts are described in more
262 detail in the following sections.</p>
263
264 <h3 id="s2s">Send-to-sync messages</h3>
265
266 <p>A send-to-sync (collapsible) message is often a &quot;tickle&quot; that tells
267 a mobile application to sync data from the server. For example, suppose you have
268 an email application. When a user receives new email on the server, the server
269 pings the mobile application with a &quot;New mail&quot; message. This tells the
270 application to sync to the server to pick up the new email. The server might send
271 this message multiple times as new mail continues to accumulate, before the application
272 has had a chance to sync. But if the user has received 25 new emails, there's no
273 need to preserve every &quot;New mail&quot; message. One is sufficient. Another
274 example would be a sports application that updates users with the latest score.
275 Only the most recent message is relevant, so it makes sense to have each new
276 message replace the preceding message. </p>
277
278 <p>The email and sports applications are cases where you would probably use the
279 GCM <code>collapse_key</code> parameter. A <em>collapse key</em> is an arbitrary
280 string that is used to collapse a group of like messages when the device is offline,
281 so that only the most recent message gets sent to the client. For example,
282 &quot;New mail,&quot; &quot;Updates available,&quot; and so on</p>
283 <p>GCM allows a maximum of 4 different collapse keys to be used by the GCM server
284 at any given time. In other words, the GCM server can simultaneously store 4
285 different send-to-sync messages per device, each with a different collapse key.
286 For example, Device A can have A1, A2, A3, and A4. Device B can have B1, B2, B3,
287 and B4, and so on. If you exceed this number GCM will only keep 4 collapse keys, with no
288 guarantees about which ones they will be.</p>
289
290 <h3 id="payload">Messages with payload</h3>
291
292 <p>Unlike a send-to-sync message, every &quot;message with payload&quot;
293 (non-collapsible message) is delivered. The payload the message contains can be
294 up to 4kb. For example, here is a JSON-formatted message in an IM application in
295 which spectators are discussing a sporting event:</p>
296
297 <pre class="prettyprint pretty-json">{
298   "registration_id" : "APA91bHun4MxP5egoKMwt2KZFBaFUH-1RYqx...",
299   "data" : {
300     "Nick" : "Mario",
301     "Text" : "great match!",
302     "Room" : "PortugalVSDenmark",
303   },
304 }</pre>
305
306 <p>A &quot;message with payload&quot; is not simply a &quot;ping&quot; to the
307 mobile application to contact the server to fetch data. In the aforementioned IM
308 application, for example, you would want to deliver every message, because every
309 message has different content. To specify a non-collapsible message, you simply
310 omit the <code>collapse_key</code> parameter. Thus GCM will send each message
311 individually. Note that the order of delivery is not guaranteed.</p>
312
313 <p>GCM will store up to 100 non-collapsible messages. After that, all messages
314 are discarded from GCM, and a new message is created that tells the client how
315 far behind it is. The message is delivered through a regular
316 <code>com.google.android.c2dm.intent.RECEIVE</code> intent with the
317 extra <code>message_type</code>, for which the value is always the string
318 &quot;deleted_messages&quot;.</p>
319
320 <p>The application should respond by syncing with the server to recover the
321 discarded messages. </p>
322
323 <h3 id="which">Which should I use?</h3>
324   <p>If your application does not need to use non-collapsible messages, collapsible
325 messages are a better choice from a performance standpoint, because they put less
326 of a burden on the device battery. However, if you use collapsible messages, remember that
327 <strong>GCM only allows a maximum of 4 different collapse keys to be used by the GCM server
328 per device at any given time</strong>. You must not exceed this number, or it could cause
329 unpredictable consequences.</p>
330
331 <h2 dir="ltr" id="ttl">Setting an Expiration Date for a Message</h2>
332 <p>The Time to Live (TTL) feature lets  the sender  specify the maximum lifespan
333 of a message using the <code>time_to_live</code> parameter in the send request.
334 The value of this parameter must be a duration from 0 to 2,419,200 seconds, and
335 it corresponds to the maximum period of time for which GCM will store and try to
336 deliver the message. Requests that don't contain this field default to the maximum
337 period of 4 weeks.</p>
338 <p>Here are some possible uses for this feature:</p>
339 <ul>
340   <li>Video chat incoming calls</li>
341   <li>Expiring invitation events</li>
342   <li>Calendar events</li>
343 </ul>
344 <h3 id="bg">Background </h3>
345 <p>GCM will usually deliver messages immediately after they are sent. However,
346 this might not always be possible. For example, the device could be turned off,
347 offline, or otherwise unavailable. In other cases, the sender itself might request
348 that messages not be delivered until the device becomes active by using the
349 <code>delay_while_idle</code> flag. Finally, GCM might intentionally delay messages
350 to prevent an application from consuming excessive resources and negatively
351 impacting battery life.</p>
352
353 <p>When this happens, GCM will store the message and deliver it as soon as it's
354 feasible. While this is fine in most cases, there are some applications for which
355 a late message might as well never be delivered. For example, if the message is
356 an incoming call or video chat notification, it will only be meaningful for a
357 small period of time before the call is terminated. Or if the message is an
358 invitation to an event, it will be useless if received after the event has ended.</p>
359
360 <p>Another advantage of specifying the expiration date for a message is that GCM
361 will never throttle messages with a <code>time_to_live</code> value of 0 seconds.
362 In other words, GCM will guarantee best effort for messages that must be delivered
363 &quot;now or never.&quot; Keep in mind that a <code>time_to_live</code> value of
364 0 means messages that can't be delivered immediately will be discarded. However,
365 because such messages are never stored, this provides the best latency for
366 sending notifications.</p>
367
368 <p>Here is an example of a JSON-formatted request that includes TTL:</p>
369 <pre class="prettyprint pretty-json">
370 {
371   "collapse_key" : "demo",
372   "delay_while_idle" : true,
373   "registration_ids" : ["xyz"],
374   "data" : {
375     "key1" : "value1",
376     "key2" : "value2",
377   },
378   "time_to_live" : 3
379 },
380 </pre>
381
382
383 <h2 id="multi-senders">Receiving Messages from Multiple Senders</h2>
384
385 <p>GCM allows multiple parties to send messages to the same application. For
386 example, suppose your application is an articles aggregator with multiple
387 contributors, and you want each of them to be able to send a message when they
388 publish a new article. This message might contain a URL so that the application
389 can download the article. Instead of having to centralize all sending activity in
390 one location, GCM gives you the ability to let each of these contributors send
391 its own messages.</p>
392
393 <p>To make this possible, all you need to do is have each sender generate its own
394 project number. Then include those IDs in the sender field, separated by commas,
395 when requesting a registration. Finally, share the registration ID with your
396 partners, and they'll be able to send messages to your application using their
397 own authentication keys.</p>
398 <p>This code snippet illustrates this feature. Senders are passed as an intent
399 extra in a comma-separated list:</p>
400
401 <pre class="prettyprint pretty-java">Intent intent = new Intent(GCMConstants.INTENT_TO_GCM_REGISTRATION);
402 intent.setPackage(GSF_PACKAGE);
403 intent.putExtra(GCMConstants.EXTRA_APPLICATION_PENDING_INTENT,
404         PendingIntent.getBroadcast(context, 0, new Intent(), 0));
405 String senderIds = &quot;968350041068,652183961211&quot;;
406 intent.putExtra(GCMConstants.EXTRA_SENDER, senderIds);
407 ontext.startService(intent);
408  </pre>
409
410 <p>Note that there is limit of 100 multiple senders.</p>