1page.title=Making the Most of Google Cloud Messaging 2 3trainingnavtop=true 4 5@jd:body 6 7<div id="tb-wrapper"> 8 <div id="tb"> 9 <h2>This lesson teaches you to</h2> 10 <ol> 11 <li><a href="#multicast">Send Multicast Messages Efficiently</a></li> 12 <li><a href="#collapse">Collapse Messages that can Be Replaced</a></li> 13 <li><a href="#embed">Embed Data Directly in the GCM Message</a></li> 14 <li><a href="#react">React Intelligently to GCM Messages</a></li> 15 </ol> 16 <h2>You should also read</h2> 17 <ul> 18 <li><a href="http://developer.android.com/google/gcm/index.html">Google 19 Cloud Messaging for Android</a></li> 20 </ul> 21 </div> 22</div> 23 24<p>Google Cloud Messaging (GCM) is a free service for sending 25messages to Android devices. GCM messaging can greatly enhance the user 26experience. Your application can stay up to date without wasting battery power 27on waking up the radio and polling the server when there are no updates. Also, 28GCM allows you to attach up to 1,000 recipients to a single message, letting you easily contact 29large user bases quickly when appropriate, while minimizing the work load on 30your server.</p> 31 32<p>This lesson covers some of the best practices 33for integrating GCM into your application, and assumes you are already familiar 34with basic implementation of this service. If this is not the case, you can read the <a 35 href="{@docRoot}google/gcm/demo.html">GCM demo app tutorial</a>.</p> 36 37<h2 id="multicast">Send Multicast Messages Efficiently</h2> 38<p>One of the most useful features in GCM is support for up to 1,000 recipients for 39a single message. This capability makes it much easier to send out important messages to 40your entire user base. For instance, let's say you had a message that needed to 41be sent to 1,000,000 of your users, and your server could handle sending out 42about 500 messages per second. If you send each message with only a single 43recipient, it would take 1,000,000/500 = 2,000 seconds, or around half an hour. 44However, attaching 1,000 recipients to each message, the total time required to 45send a message out to 1,000,000 recipients becomes (1,000,000/1,000) / 500 = 2 46seconds. This is not only useful, but important for timely data, such as natural 47disaster alerts or sports scores, where a 30 minute interval might render the 48information useless.</p> 49 50<p>Taking advantage of this functionality is easy. If you're using the <a 51 href="{@docRoot}google/gcm/gs.html#libs">GCM helper 52 library</a> for Java, simply provide a <code>List<String></code> collection of 53registration IDs to the <code>send</code> or <code>sendNoRetry</code> method, 54instead of a single registration ID.</p> 55 56<pre> 57// This method name is completely fabricated, but you get the idea. 58List<String> regIds = whoShouldISendThisTo(message); 59 60// If you want the SDK to automatically retry a certain number of times, use the 61// standard send method. 62MulticastResult result = sender.send(message, regIds, 5); 63 64// Otherwise, use sendNoRetry. 65MulticastResult result = sender.sendNoRetry(message, regIds); 66</pre> 67 68<p>For those implementing GCM support in a language other than Java, construct 69an HTTP POST request with the following headers:</p> 70<ul> 71 <li><code>Authorization: key=YOUR_API_KEY</code></li> 72 <li><code>Content-type: application/json</code></li> 73</ul> 74 75<p>Then encode the parameters you want into a JSON object, listing all the 76registration IDs under the key <code>registration_ids</code>. The snippet below 77serves as an example. All parameters except <code>registration_ids</code> are 78optional, and the items nested in <code>data</code> represent the user-defined payload, not 79GCM-defined parameters. The endpoint for this HTTP POST message will be 80<code>https://android.googleapis.com/gcm/send</code>.</p> 81 82<pre> 83{ "collapse_key": "score_update", 84 "time_to_live": 108, 85 "delay_while_idle": true, 86 "data": { 87 "score": "4 x 8", 88 "time": "15:16.2342" 89 }, 90 "registration_ids":["4", "8", "15", "16", "23", "42"] 91} 92</pre> 93 94<p>For a more thorough overview of the format of multicast GCM messages, see the <a 95 href="{@docRoot}google/gcm/gcm.html#send-msg">Sending 96 Messages</a> section of the GCM guide.</pre> 97 98<h2 id="collapse">Collapse Messages that Can Be Replaced</h2> 99<p>GCM messages are often a tickle, telling the mobile application to 100contact the server for fresh data. In GCM, it's possible (and recommended) to 101create collapsible messages for this situation, wherein new messages replace 102older ones. Let's take the example 103of sports scores. If you send out a message to all users following a certain 104game with the updated score, and then 15 minutes later an updated score message 105goes out, the earlier one no longer matters. For any users who haven't received 106the first message yet, there's no reason to send both, and force the device to 107react (and possibly alert the user) twice when only one of the messages is still 108important.</p> 109 110<p>When you define a collapse key, when multiple messages are queued up in the GCM 111servers for the same user, only the last one with any given collapse key is 112delivered. For a situation like with sports scores, this saves the device from 113doing needless work and potentially over-notifying the user. For situations 114that involve a server sync (like checking email), this can cut down on the 115number of syncs the device has to do. For instance, if there are 10 emails 116waiting on the server, and ten "new email" GCM tickles have been sent to the 117device, it only needs one, since it should only sync once.</p> 118 119<p>In order to use this feature, just add a collapse key to your outgoing 120message. If you're using the GCM helper library, use the Message class's <code>collapseKey(String key)</code> method.</p> 121 122<pre> 123Message message = new Message.Builder(regId) 124 .collapseKey("game4_scores") // The key for game 4. 125 .ttl(600) // Time in seconds to keep message queued if device offline. 126 .delayWhileIdle(true) // Wait for device to become active before sending. 127 .addPayload("key1", "value1") 128 .addPayload("key2", "value2") 129 .build(); 130</pre> 131 132<p>If not using the helper library, simply add a variable to the 133POST header you're constructing, with <code>collapse_key</code> as the field 134name, and the string you're using for that set of updates as the value.</p> 135 136 137 138<h2 id="embed">Embed Data Directly in the GCM Message</h2> 139<p>Often, GCM messages are meant to be a tickle, or indication to the device 140that there's fresh data waiting on a server somewhere. However, a GCM message 141can be up to 4kb in size, so sometimes it makes sense to simply send the 142data within the GCM message itself, so that the device doesn't need to contact the 143server at all. Consider this approach for situations where all of the 144following statements are true: 145<ul> 146 <li>The total data fits inside the 4kb limit.</li> 147 <li>Each message is important, and should be preserved.</li> 148 <li>It doesn't make sense to collapse multiple GCM messages into a single 149 "new data on the server" tickle.</li> 150</ul> 151 152<p>For instance, short messages or encoded player moves 153in a turn-based network game are examples of good use-cases for data to embed directly 154into a GCM message. Email is an example of a bad use-case, since messages are 155often larger than 4kb, 156and users don't need a GCM message for each email waiting for them on 157the server.</p> 158 159<p>Also consider this approach when sending 160multicast messages, so you don't tell every device across your user base to hit 161your server for updates simultaneously.</p> 162<p>This strategy isn't appropriate for sending large amounts of data, for a few 163reasons:</p> 164<ul> 165 <li>Rate limits are in place to prevent malicious or poorly coded apps from spamming an 166 individual device with messages.</li> 167 <li>Messages aren't guaranteed to arrive in-order.</li> 168 <li>Messages aren't guaranteed to arrive as fast as you send them out. Even 169 if the device receives one GCM message a second, at a max of 1K, that's 8kbps, or 170 about the speed of home dial-up internet in the early 1990's. Your app rating 171 on Google Play will reflect having done that to your users.</p> 172</ul> 173 174<p>When used appropriately, directly embedding data in the GCM message can speed 175up the perceived speediness of your application, by letting it skip a round trip 176to the server.</p> 177 178<h2 id="react">React Intelligently to GCM Messages</h2> 179<p>Your application should not only react to incoming GCM messages, but react 180<em>intelligently</em>. How to react depends on the context.</p> 181 182<h3>Don't be irritating</h3> 183<p>When it comes to alerting your user of fresh data, it's easy to cross the line 184from "useful" to "annoying". If your application uses status bar notifications, 185<a 186 href="http://developer.android.com/guide/topics/ui/notifiers/notifications.html#Updating">update 187 your existing notification</a> instead of creating a second one. If you 188beep or vibrate to alert the user, consider setting up a timer. Don't let the 189application alert more than once a minute, lest users be tempted to uninstall 190your application, turn the device off, or toss it in a nearby river.</p> 191 192<h3>Sync smarter, not harder</h3> 193<p>When using GCM as an indicator to the device that data needs to be downloaded 194from the server, remember you have 4kb of metadata you can send along to 195help your application be smart about it. For instance, if you have a feed 196reading app, and your user has 100 feeds that they follow, help the device be 197smart about what it downloads from the server! Look at the following examples 198of what metadata is sent to your application in the GCM payload, and how the application 199can react:</p> 200<ul> 201 <li><code>refresh</code> — Your app basically got told to request a dump of 202 every feed it follows. Your app would either need to send feed requests to 100 different servers, or 203 if you have an aggregator on your server, send a request to retrieve, bundle 204 and 205 transmit recent data from 100 different feeds, every time one updates.</li> 206 <li><code>refresh</code>, <code>feedID</code> — Better: Your app knows to check 207 a specific feed for updates.</li> 208 <li><code>refresh</code>, <code>feedID</code>, <code>timestamp</code> — 209 Best: If the user happened to manually refresh before the GCM message 210 arrived, the application can compare timestamps of the most recent post, and 211 determine that it <em>doesn't need to do anything</em>. 212</ul> 213