| Katie McCormick | 76c6d86 | 2012-06-25 09:56:29 -0700 | [diff] [blame] | 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> |
| Katie McCormick | 0ab9326 | 2013-11-01 18:10:51 -0700 | [diff] [blame] | 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> |
| Katie McCormick | 76c6d86 | 2012-06-25 09:56:29 -0700 | [diff] [blame] | 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> |
| Katie McCormick | 60c8f99 | 2012-07-12 11:57:36 -0700 | [diff] [blame] | 35 | <li><a href="#which">Which should I use?</a></li> |
| Katie McCormick | 76c6d86 | 2012-06-25 09:56:29 -0700 | [diff] [blame] | 36 | </ol> |
| 37 | </li> |
| 38 | <li><a href="#ttl">Setting an Expiration Date for a Message</a> </li> |
| Katie McCormick | 0ab9326 | 2013-11-01 18:10:51 -0700 | [diff] [blame] | 39 | <li><a href="#throttling"></a><a href="#multi-senders">Receiving Messages from |
| 40 | Multiple Senders</a></li> |
| Katie McCormick | 76c6d86 | 2012-06-25 09:56:29 -0700 | [diff] [blame] | 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> |
| Katie McCormick | 0ab9326 | 2013-11-01 18:10:51 -0700 | [diff] [blame] | 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 | |
| Katie McCormick | 76c6d86 | 2012-06-25 09:56:29 -0700 | [diff] [blame] | 60 | <p>If the device is connected but idle, the message will still be |
| Katie McCormick | 0ab9326 | 2013-11-01 18:10:51 -0700 | [diff] [blame] | 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> |
| Katie McCormick | 76c6d86 | 2012-06-25 09:56:29 -0700 | [diff] [blame] | 69 | |
| Katie McCormick | 0ab9326 | 2013-11-01 18:10:51 -0700 | [diff] [blame] | 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> |
| Katie McCormick | 76c6d86 | 2012-06-25 09:56:29 -0700 | [diff] [blame] | 84 | |
| Katie McCormick | 0ab9326 | 2013-11-01 18:10:51 -0700 | [diff] [blame] | 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> |
| Katie McCormick | 76c6d86 | 2012-06-25 09:56:29 -0700 | [diff] [blame] | 92 | |
| Katie McCormick | 0ab9326 | 2013-11-01 18:10:51 -0700 | [diff] [blame] | 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 |
| Katie McCormick | 6b37262 | 2013-11-15 16:02:58 -0800 | [diff] [blame] | 99 | Google Cloud Console stats are broken down by messages sent to device, messages |
| Katie McCormick | 0ab9326 | 2013-11-01 18:10:51 -0700 | [diff] [blame] | 100 | collapsed, and messages waiting for delivery.</p> |
| Katie McCormick | 76c6d86 | 2012-06-25 09:56:29 -0700 | [diff] [blame] | 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> |
| Katie McCormick | 0ab9326 | 2013-11-01 18:10:51 -0700 | [diff] [blame] | 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 | |
| Katie McCormick | 76c6d86 | 2012-06-25 09:56:29 -0700 | [diff] [blame] | 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> |
| Katie McCormick | 0ab9326 | 2013-11-01 18:10:51 -0700 | [diff] [blame] | 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> |
| Katie McCormick | 76c6d86 | 2012-06-25 09:56:29 -0700 | [diff] [blame] | 142 | |
| Katie McCormick | 0ab9326 | 2013-11-01 18:10:51 -0700 | [diff] [blame] | 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—thus the application will not get more |
| 148 | messages).</p> |
| Katie McCormick | 76c6d86 | 2012-06-25 09:56:29 -0700 | [diff] [blame] | 149 | <h3 id="canonical">Canonical IDs</h3> |
| Katie McCormick | 0ab9326 | 2013-11-01 18:10:51 -0700 | [diff] [blame] | 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 "canonical registration IDs" 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> |
| Katie McCormick | 76c6d86 | 2012-06-25 09:56:29 -0700 | [diff] [blame] | 163 | |
| 164 | <h2 id="retry">Automatic Retry Using Exponential Back-Off</h2> |
| 165 | |
| Katie McCormick | 0ab9326 | 2013-11-01 18:10:51 -0700 | [diff] [blame] | 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. |
| Katie McCormick | 76c6d86 | 2012-06-25 09:56:29 -0700 | [diff] [blame] | 175 | |
| Katie McCormick | 0ab9326 | 2013-11-01 18:10:51 -0700 | [diff] [blame] | 176 | <h2 id="unreg">Unregistration</h2> |
| Katie McCormick | 76c6d86 | 2012-06-25 09:56:29 -0700 | [diff] [blame] | 177 | |
| Katie McCormick | 0ab9326 | 2013-11-01 18:10:51 -0700 | [diff] [blame] | 178 | <p>This section explains when you should unregister in GCM and what happens |
| 179 | when you do.</p> |
| Katie McCormick | 76c6d86 | 2012-06-25 09:56:29 -0700 | [diff] [blame] | 180 | |
| Katie McCormick | 0ab9326 | 2013-11-01 18:10:51 -0700 | [diff] [blame] | 181 | <h3 id="unreg-why">Why you should rarely unregister</h3> |
| Katie McCormick | 76c6d86 | 2012-06-25 09:56:29 -0700 | [diff] [blame] | 182 | |
| Katie McCormick | 0ab9326 | 2013-11-01 18:10:51 -0700 | [diff] [blame] | 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> |
| Katie McCormick | 76c6d86 | 2012-06-25 09:56:29 -0700 | [diff] [blame] | 188 | |
| Katie McCormick | 0ab9326 | 2013-11-01 18:10:51 -0700 | [diff] [blame] | 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> |
| Katie McCormick | 76c6d86 | 2012-06-25 09:56:29 -0700 | [diff] [blame] | 191 | |
| Katie McCormick | 0ab9326 | 2013-11-01 18:10:51 -0700 | [diff] [blame] | 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—there's no guarantee either way.</li> |
| Katie McCormick | 76c6d86 | 2012-06-25 09:56:29 -0700 | [diff] [blame] | 196 | |
| Katie McCormick | 0ab9326 | 2013-11-01 18:10:51 -0700 | [diff] [blame] | 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> |
| Katie McCormick | 76c6d86 | 2012-06-25 09:56:29 -0700 | [diff] [blame] | 202 | |
| Katie McCormick | 76c6d86 | 2012-06-25 09:56:29 -0700 | [diff] [blame] | 203 | |
| Katie McCormick | 0ab9326 | 2013-11-01 18:10:51 -0700 | [diff] [blame] | 204 | <p>The solution is to manage your own mapping between users, the regID, and |
| 205 | individual messages:</p> |
| Katie McCormick | 76c6d86 | 2012-06-25 09:56:29 -0700 | [diff] [blame] | 206 | |
| Katie McCormick | 0ab9326 | 2013-11-01 18:10:51 -0700 | [diff] [blame] | 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> |
| Katie McCormick | 76c6d86 | 2012-06-25 09:56:29 -0700 | [diff] [blame] | 214 | |
| Katie McCormick | 76c6d86 | 2012-06-25 09:56:29 -0700 | [diff] [blame] | 215 | |
| Katie McCormick | 0ab9326 | 2013-11-01 18:10:51 -0700 | [diff] [blame] | 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> |
| Katie McCormick | 76c6d86 | 2012-06-25 09:56:29 -0700 | [diff] [blame] | 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> |
| Katie McCormick | 0ab9326 | 2013-11-01 18:10:51 -0700 | [diff] [blame] | 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>. |
| Katie McCormick | c44ba47 | 2012-08-20 12:38:08 -0700 | [diff] [blame] | 228 | </li> |
| Katie McCormick | 76c6d86 | 2012-06-25 09:56:29 -0700 | [diff] [blame] | 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> |
| && repo sync -j8 | 4fd6c20 | 2012-09-27 16:09:14 -0700 | [diff] [blame] | 236 | |
| Katie McCormick | 0ab9326 | 2013-11-01 18:10:51 -0700 | [diff] [blame] | 237 | <p class ="note"><strong>Note:</strong> The GCM client is the Google Cloud |
| 238 | Messaging framework present on the device.</p> |
| && repo sync -j8 | 4fd6c20 | 2012-09-27 16:09:14 -0700 | [diff] [blame] | 239 | |
| Katie McCormick | 0ab9326 | 2013-11-01 18:10:51 -0700 | [diff] [blame] | 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> |
| Katie McCormick | 76c6d86 | 2012-06-25 09:56:29 -0700 | [diff] [blame] | 247 | |
| 248 | <h2 id="collapsible">Send-to-Sync vs. Messages with Payload</h2> |
| Katie McCormick | 60c8f99 | 2012-07-12 11:57:36 -0700 | [diff] [blame] | 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 | |
| Katie McCormick | 0ab9326 | 2013-11-01 18:10:51 -0700 | [diff] [blame] | 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 "send-to-sync" (collapsible) message or a "message with |
| 261 | payload" (non-collapsible message). These concepts are described in more |
| 262 | detail in the following sections.</p> |
| Katie McCormick | 60c8f99 | 2012-07-12 11:57:36 -0700 | [diff] [blame] | 263 | |
| Katie McCormick | 76c6d86 | 2012-06-25 09:56:29 -0700 | [diff] [blame] | 264 | <h3 id="s2s"><strong>Send-to-sync messages</strong></h3> |
| Katie McCormick | 60c8f99 | 2012-07-12 11:57:36 -0700 | [diff] [blame] | 265 | |
| Katie McCormick | 0ab9326 | 2013-11-01 18:10:51 -0700 | [diff] [blame] | 266 | <p>A send-to-sync (collapsible) message is often a "tickle" 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 "New mail" 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 "New mail" 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> |
| Katie McCormick | 60c8f99 | 2012-07-12 11:57:36 -0700 | [diff] [blame] | 277 | |
| Katie McCormick | 0ab9326 | 2013-11-01 18:10:51 -0700 | [diff] [blame] | 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 | "New mail," "Updates available," 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> |
| Katie McCormick | 60c8f99 | 2012-07-12 11:57:36 -0700 | [diff] [blame] | 289 | |
| Katie McCormick | 76c6d86 | 2012-06-25 09:56:29 -0700 | [diff] [blame] | 290 | <h3 id="payload">Messages with payload</h3> |
| Katie McCormick | 0ab9326 | 2013-11-01 18:10:51 -0700 | [diff] [blame] | 291 | <p>Unlike a send-to-sync message, every "message with payload" |
| 292 | (non-collapsible message) is delivered. The payload the message contains can be |
| 293 | up to 4kb. For example, here is a JSON-formatted message in an IM application in |
| 294 | which spectators are discussing a sporting event:</p> |
| Katie McCormick | 76c6d86 | 2012-06-25 09:56:29 -0700 | [diff] [blame] | 295 | |
| 296 | <pre class="prettyprint pretty-json">{ |
| 297 | "registration_id" : "APA91bHun4MxP5egoKMwt2KZFBaFUH-1RYqx...", |
| 298 | "data" : { |
| 299 | "Nick" : "Mario", |
| 300 | "Text" : "great match!", |
| 301 | "Room" : "PortugalVSDenmark", |
| 302 | }, |
| 303 | }</pre> |
| 304 | |
| Katie McCormick | 0ab9326 | 2013-11-01 18:10:51 -0700 | [diff] [blame] | 305 | <p>A "message with payload" is not simply a "ping" to the |
| 306 | mobile application to contact the server to fetch data. In the aforementioned IM |
| 307 | application, for example, you would want to deliver every message, because every |
| 308 | message has different content. To specify a non-collapsible message, you simply |
| 309 | omit the <code>collapse_key</code> parameter. Thus GCM will send each message |
| 310 | individually. Note that the order of delivery is not guaranteed.</p> |
| 311 | |
| 312 | <p>GCM will store up to 100 non-collapsible messages. After that, all messages |
| 313 | are discarded from GCM, and a new message is created that tells the client how |
| 314 | far behind it is. The message is delivered through a regular |
| Katie McCormick | 6b37262 | 2013-11-15 16:02:58 -0800 | [diff] [blame] | 315 | <code>com.google.android.c2dm.intent.RECEIVE</code> intent with the |
| 316 | extra <code>message_type</code>, for which the value is always the string |
| 317 | "deleted_messages".</p> |
| 318 | |
| Katie McCormick | 0ab9326 | 2013-11-01 18:10:51 -0700 | [diff] [blame] | 319 | <p>The application should respond by syncing with the server to recover the |
| 320 | discarded messages. </p> |
| Katie McCormick | 60c8f99 | 2012-07-12 11:57:36 -0700 | [diff] [blame] | 321 | |
| 322 | <h3 id="which">Which should I use?</h3> |
| Katie McCormick | 0ab9326 | 2013-11-01 18:10:51 -0700 | [diff] [blame] | 323 | <p>If your application does not need to use non-collapsible messages, collapsible |
| 324 | messages are a better choice from a performance standpoint, because they put less |
| 325 | of a burden on the device battery. However, if you use collapsible messages, remember that |
| 326 | <strong>GCM only allows a maximum of 4 different collapse keys to be used by the GCM server |
| 327 | per device at any given time</strong>. You must not exceed this number, or it could cause |
| 328 | unpredictable consequences.</p> |
| Katie McCormick | 60c8f99 | 2012-07-12 11:57:36 -0700 | [diff] [blame] | 329 | |
| Katie McCormick | 76c6d86 | 2012-06-25 09:56:29 -0700 | [diff] [blame] | 330 | <h2 dir="ltr" id="ttl">Setting an Expiration Date for a Message</h2> |
| Katie McCormick | 0ab9326 | 2013-11-01 18:10:51 -0700 | [diff] [blame] | 331 | <p>The Time to Live (TTL) feature lets the sender specify the maximum lifespan |
| 332 | of a message using the <code>time_to_live</code> parameter in the send request. |
| 333 | The value of this parameter must be a duration from 0 to 2,419,200 seconds, and |
| 334 | it corresponds to the maximum period of time for which GCM will store and try to |
| 335 | deliver the message. Requests that don't contain this field default to the maximum |
| 336 | period of 4 weeks.</p> |
| Katie McCormick | 76c6d86 | 2012-06-25 09:56:29 -0700 | [diff] [blame] | 337 | <p>Here are some possible uses for this feature:</p> |
| 338 | <ul> |
| 339 | <li>Video chat incoming calls</li> |
| 340 | <li>Expiring invitation events</li> |
| 341 | <li>Calendar events</li> |
| 342 | </ul> |
| 343 | <h3 id="bg">Background </h3> |
| Katie McCormick | 0ab9326 | 2013-11-01 18:10:51 -0700 | [diff] [blame] | 344 | <p>GCM will usually deliver messages immediately after they are sent. However, |
| 345 | this might not always be possible. For example, the device could be turned off, |
| 346 | offline, or otherwise unavailable. In other cases, the sender itself might request |
| 347 | that messages not be delivered until the device becomes active by using the |
| 348 | <code>delay_while_idle</code> flag. Finally, GCM might intentionally delay messages |
| 349 | to prevent an application from consuming excessive resources and negatively |
| 350 | impacting battery life.</p> |
| 351 | |
| 352 | <p>When this happens, GCM will store the message and deliver it as soon as it's |
| 353 | feasible. While this is fine in most cases, there are some applications for which |
| 354 | a late message might as well never be delivered. For example, if the message is |
| 355 | an incoming call or video chat notification, it will only be meaningful for a |
| 356 | small period of time before the call is terminated. Or if the message is an |
| 357 | invitation to an event, it will be useless if received after the event has ended.</p> |
| 358 | |
| 359 | <p>Another advantage of specifying the expiration date for a message is that GCM |
| 360 | will never throttle messages with a <code>time_to_live</code> value of 0 seconds. |
| 361 | In other words, GCM will guarantee best effort for messages that must be delivered |
| 362 | "now or never." Keep in mind that a <code>time_to_live</code> value of |
| 363 | 0 means messages that can't be delivered immediately will be discarded. However, |
| 364 | because such messages are never stored, this provides the best latency for |
| 365 | sending notifications.</p> |
| 366 | |
| Katie McCormick | 76c6d86 | 2012-06-25 09:56:29 -0700 | [diff] [blame] | 367 | <p>Here is an example of a JSON-formatted request that includes TTL:</p> |
| 368 | <pre class="prettyprint pretty-json"> |
| 369 | { |
| 370 | "collapse_key" : "demo", |
| 371 | "delay_while_idle" : true, |
| 372 | "registration_ids" : ["xyz"], |
| 373 | "data" : { |
| 374 | "key1" : "value1", |
| 375 | "key2" : "value2", |
| 376 | }, |
| 377 | "time_to_live" : 3 |
| 378 | }, |
| 379 | </pre> |
| 380 | |
| 381 | |
| 382 | <h2 id="multi-senders">Receiving Messages from Multiple Senders</h2> |
| Katie McCormick | 0ab9326 | 2013-11-01 18:10:51 -0700 | [diff] [blame] | 383 | |
| 384 | <p>GCM allows multiple parties to send messages to the same application. For |
| 385 | example, suppose your application is an articles aggregator with multiple |
| 386 | contributors, and you want each of them to be able to send a message when they |
| 387 | publish a new article. This message might contain a URL so that the application |
| 388 | can download the article. Instead of having to centralize all sending activity in |
| 389 | one location, GCM gives you the ability to let each of these contributors send |
| 390 | its own messages.</p> |
| 391 | |
| 392 | <p>To make this possible, all you need to do is have each sender generate its own |
| 393 | project number. Then include those IDs in the sender field, separated by commas, |
| 394 | when requesting a registration. Finally, share the registration ID with your |
| 395 | partners, and they'll be able to send messages to your application using their |
| 396 | own authentication keys.</p> |
| 397 | <p>This code snippet illustrates this feature. Senders are passed as an intent |
| 398 | extra in a comma-separated list:</p> |
| 399 | |
| Katie McCormick | 76c6d86 | 2012-06-25 09:56:29 -0700 | [diff] [blame] | 400 | <pre class="prettyprint pretty-java">Intent intent = new Intent(GCMConstants.INTENT_TO_GCM_REGISTRATION); |
| 401 | intent.setPackage(GSF_PACKAGE); |
| 402 | intent.putExtra(GCMConstants.EXTRA_APPLICATION_PENDING_INTENT, |
| 403 | PendingIntent.getBroadcast(context, 0, new Intent(), 0)); |
| 404 | String senderIds = "968350041068,652183961211"; |
| 405 | intent.putExtra(GCMConstants.EXTRA_SENDER, senderIds); |
| 406 | ontext.startService(intent); |
| 407 | </pre> |
| 408 | |
| 409 | <p>Note that there is limit of 100 multiple senders.</p> |