1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
|
page.title=User Notifications
@jd:body
<div id="qv-wrapper">
<div id="qv">
<h2>Quickview</h2>
<ul>
<li>Learn how to send a single message to multiple devices owned by a single user.</li>
</ul>
<h2>In this document</h2>
<ol class="toc">
<li><a href="#gen-server">Generate a Notification Key on the Server</a></li>
<li><a href="#gen-client">Generate a Notification Key on the Client</a></li>
<li><a href="#add">Add Registration IDs</a></li>
<li><a href="#remove">Remove Registration IDs</a></li>
<li><a href="#upstream">Send Upstream Messages</a></li>
<li><a href="#response">Response Formats</a>
<ol class="toc">
<li><a href="#response-create">Create/add/remove operations</a>
<li><a href="#response-send">Send operations</a>
</ol>
</li>
</ol>
<h2>See Also</h2>
<ol class="toc">
<li><a href="{@docRoot}google/gcm/gs.html">Getting Started</a></li>
</ol>
</div>
</div>
<p>With user notifications, 3rd-party app servers can send a single message to
multiple instance of an app running on devices owned by a single user. This feature
is called <em>user notifications</em>. User notifications make it possible for every
app instance that a user owns to reflect the latest messaging state. For example:</p>
<ul>
<li>If a message has been handled on one device, the GCM message on the other
devices are dismissed. For example, if a user has handled a calendar notification
on one device, the notification will go away on the user's other devices.</li>
<li>If a message has not been delivered yet to a device and but it has been handled,
the GCM server removes it from the unsent queue for the other devices.</li>
<li>Likewise, a device can send messages to the {@code notification_key}, which
is the token that GCM uses to fan out notifications to all devices whose
registration IDs are associated with the key.</li>
</ul>
<p>The way this works is that during registration, the 3rd-party server requests
a {@code notification_key}. The {@code notification_key} maps a particular user
to all of the user's associated registration IDs (a regID represents a particular
Android application running on a particular device). Then instead of sending one
message to one regID at a time, the 3rd-party server can send a message to to the
{@code notification_key}, which then sends the message to all of the user's regIDs.</p>
<p class="note"><strong>Note:</strong> A notification dismissal message is like any
other upstream message, meaning that it will be delivered to the other devices that
belong to the specified {@code notification_key}. You should design your app to
handle cases where the app receives a dismissal message, but has not yet displayed
the notification that is being dismissed. You can solve this by caching the dismissal
and then reconciling it with the corresponding notification.
</p>
<p>You can use this feature with either the <a href="ccs.html">XMPP</a> (CCS) or
<a href="http.html">HTTP</a> connection server.</p>
<p>You can generate notification keys in two different ways: on the server, and on
the client, if the user has a Google account. All of the associated registration IDs
can be mapped to a single user.</p>
<p>The examples below show you how to perform generate/add/remove operations,
and how to send upstream messages. For generate/add/remove operations, the
message body is JSON.</p>
<h2 id="gen-server">Generate a Notification Key on the Server</h2>
<p>To generate a notification key on the server, you create a new
<code>notification_key</code> and map it to a
<code>notification_key_name</code>.</p>
<p>This example shows how to create a new <code>notification_key</code> for a
<code>notification_key_name</code> called <code>appUser-Chris</code>.
The {@code notification_key_name} is a name or identifier (it can be a username for
a 3rd-party app) that is unique to a given user. It is used by third parties to
group together registration IDs for a single user. Note that <code>notification_key_name</code>
and <code>notification_key</code> are unique to a group of registration IDs. It is also
important that <code>notification_key_name</code> be uniquely named per app in case
you have multiple apps for the same project ID. This ensures that notifications
only go to the intended target app.</p>
<p>A create operation returns a token (<code>notification_key</code>). Third parties
must save this token (as well as its mapping to the <code>notification_key_name</code>)
to use in subsequent operations:</p>
<pre>request:
{
"operation": "create",
"notification_key_name": "appUser-Chris",
"registration_ids": ["4", "8", "15", "16", "23", "42"]
}</pre>
<h3 id="request-server">Request format</h3>
<p>To send a message in cases where your notification key is generated on the server,
the application server issues a POST request to
<code>https://android.googleapis.com/gcm/notification</code>.</p>
<p>Here is the HTTP request header you should use for all server side create/add/remove operations:</p>
<pre>content-type: "application/json"
Header : "project_id": <projectID>
Header: "Authorization", "key=API_KEY"
</pre>
<h2 id="gen-client">Generate a Notification Key on the Client</h2>
<p>Generating a notification key on the client is useful for cases where a server is unavailable.
To generate a notification key on the client, the device must have at least one
Google account. Note that the process for generating a notification key on the client is significantly
different from the server process described above.</p>
<p>To generate a notification key on the client:</p>
<ol>
<li>Open your project in the <a href="https://cloud.google.com/console">Google Developers Console</a>.</li>
<li>Click <strong>APIS & AUTH > Credentials</strong>.</li>
<li>Under OAuth, click <strong>Create new Client ID</strong>.</li>
<li>In the <strong>Create Client ID</strong> dialog, select <strong>Web Application</strong> as
the application type, and click <strong>Create Client ID</strong>.</li>
<li>Copy the value from <strong>Client ID for web application > Client ID</strong>.
This client ID represents a Google account "scope" that you will use to generate an {@code id_token}.</li>
</ol>
<p>Once you've followed the above steps and gotten a client ID from Google Developers Console,
you're ready to add this feature to your app. First check the device for the presence of a Google
account. For example:</p>
<pre>// This snippet takes the simple approach of using the first returned Google account,
// but you can pick any Google account on the device.
public String getAccount() {
Account[] accounts = AccountManager.get(getActivity()).
getAccountsByType("com.google");
if (accounts.length == 0) {
return null;
}
return accounts[0].name;
}</pre>
<p>Next, get an authentication token ({@code id_token}) by using the <code><a href=
"http://developer.android.com/reference/com/google/android/gms/auth/GoogleAuthUtil.html">GoogleAuthUtil</a></code>
class. For example:</p>
<pre>String accountName = getAccount();
// Initialize the scope using the client ID you got from the Console.
final String scope = "audience:server:client_id:"
+ "1262xxx48712-9qs6n32447mcj9dirtnkyrejt82saa52.apps.googleusercontent.com";
String id_token = null;
try {
id_token = GoogleAuthUtil.getToken(context, accountName, scope);
} catch (Exception e) {
log("exception while getting id_token: " + e);
}
...</pre>
<p>Now use <code>id_token</code> to authenticate your request.
This add operation returns a {@code notification_key}.
Third parties must save this {@code notification_key} (as well as its mapping to the
<code>notification_key_name</code>)
to use in subsequent operations. Note that a client request only takes a single regID.
The only operations supported on the client side are add/remove.</p>
<pre>request:
{
"operation": "add",
"notification_key_name": "appUser-Chris",
"registration_ids": ["4"]
"id_token": "id_token"
}</pre>
<h3 id="request-client">Request format</h3>
<p>To send a message in cases where your notification key is generated on the client,
the application server issues a POST request to
<code>https://android.googleapis.com/gcm/googlenotification</code>.</p>
<p>Here is the HTTP request header you should use for all add/remove operations. The
client side doesn't support the create operation;
the add operation has the effect of creating the notification key if it doesn't already
exist:</p>
<pre>content-type: "application/json"
Header : "project_id": <projectID>
</pre>
<p>Note that the authentication token is passed in the JSON body as shown above, not the header.
This is different from the server case.</p>
<h2 id="add">Add Registration IDs</h2>
<p>This example shows how to add registration IDs for a given notification key.
The maximum number of members allowed for a {@code notification_key} is 20.</p>
<p>Note that the <code>notification_key_name</code> is not strictly required for
adding/removing regIDs. But including it protects you against accidentally using
the incorrect <code>notification_key</code>.</p>
<pre>request:
{
"operation": "add",
"notification_key_name": "appUser-Chris",
"notification_key": "aUniqueKey"
"registration_ids": ["4", "8", "15", "16", "23", "42"]
}</pre>
<h2 id="remove">Remove Registration IDs</h2>
<p>This example shows how to remove registration IDs for a given notification key:</p>
<pre>request:
{
"operation": "remove",
"notification_key_name": "appUser-Chris",
"notification_key": "aUniqueKey"
"registration_ids": ["4", "8", "15", "16", "23", "42"]
}</pre>
<h2 id="upstream">Send Upstream Messages</h2>
<p>To send an upstream (device-to-cloud) message, you must use the
<a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">
{@code GoogleCloudMessaging}</a> API. Specifying a {@code notification_key} as the target
for an upstream message allows a user on one device to send a message to other
devices in the notification group—for example, to dismiss a notification.
Here is an example that shows targeting a {@code notification_key}:</p>
<pre>GoogleCloudMessaging gcm = GoogleCloudMessaging.get(context);
String to = NOTIFICATION_KEY;
AtomicInteger msgId = new AtomicInteger();
String id = Integer.toString(msgId.incrementAndGet());
Bundle data = new Bundle();
data.putString("hello", "world");
gcm.send(to, id, data);
</pre>
<p>This call generates the necessary XMPP stanza for sending the message. The
Bundle data consists of a key-value pair.</p>
<p>For a complete example, see <a href="client.html">Implementing GCM Client</a>.
<h2 id="response">Response Formats</h2>
<p>This section shows examples of the responses that can be returned for
notification key operations.</p>
<h3 id="response-create">Create/add/remove operations</h3>
<p>When you make a request to create a {@code notification_key} or to add/remove its
regIDs, a successful response always returns the <code>notification_key</code>.
Use the returned {@code notification_key} for sending messages:</p>
<pre>HTTP status: 200
{
"notification_key": "aUniqueKey", // to be used for sending
}</pre>
<h3 id="response-send">Send operations</h3>
<p>For a send operation that has a {@code notification_key} as its target, the
possible responses are success, partial success, and failure.</p>
<p>Here is an example of "success"—the {@code notification_key} has 2 regIDs
associated with it, and the message was successfully sent to both of them:</p>
<pre>{
"success": 2,
"failure": 0
}</pre>
<p>Here is an example of "partial success"—the {@code notification_key} has
3 regIDs associated with it. The message was successfully send to 1 of the regIDs,
but not to the other 2. The response message lists the regIDs that failed to
receive the message:</p>
<pre>{
"success":1,
"failure":2,
"failed_registration_ids":[
"regId1",
"regId2"
]
}</pre>
<p>In the case of failure, the response has HTTP code 503 and no JSON. When a message
fails to be delivered to one or more of the regIDs associated with a {@code notification_key},
the 3rd-party server should retry.</p>
|