Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e89c6ebe authored by Katie McCormick's avatar Katie McCormick
Browse files

Doc update: GCM changes for I/O.

Fixes for:

b/15348323
b/15349955
b/15330953

Change-Id: Ie256a76ea83cf16256cded858531dd78b8da0558
parent 7cfd2e03
Loading
Loading
Loading
Loading
+110 −39
Original line number Original line Diff line number Diff line
@@ -19,7 +19,11 @@ page.title=GCM Cloud Connection Server (XMPP)
        <li><a href="#response">Response format</a></li>
        <li><a href="#response">Response format</a></li>
      </ol>
      </ol>
      </li>
      </li>
  <li><a href="#upstream">Upstream Messages</a> </li>
  <li><a href="#upstream">Upstream Messages</a>
    <ol>
      <li><a href="#receipts">Receive return receipts</a></li>
    </ol>
  </li>
  <li><a href="#flow">Flow Control</a> </li>
  <li><a href="#flow">Flow Control</a> </li>
  <li><a href="#implement">Implementing an XMPP-based App Server</a>
  <li><a href="#implement">Implementing an XMPP-based App Server</a>
    <ol class="toc">
    <ol class="toc">
@@ -43,9 +47,6 @@ target="_android">CCS and User Notifications Signup Form</a></li>
</div>
</div>
</div>
</div>


<p class="note"><strong>Note:</strong> To try out this feature, sign up using
<a href="https://services.google.com/fb/forms/gcm/">this form</a>.</p>

<p>The GCM Cloud Connection Server (CCS) is an XMPP endpoint that provides a
<p>The GCM Cloud Connection Server (CCS) is an XMPP endpoint that provides a
persistent, asynchronous, bidirectional connection to Google servers. The
persistent, asynchronous, bidirectional connection to Google servers. The
connection can be used to send and receive messages between your server and
connection can be used to send and receive messages between your server and
@@ -149,8 +150,8 @@ exceptions:</p>
  <li>CCS adds the field {@code message_id}, which is required. This ID uniquely
  <li>CCS adds the field {@code message_id}, which is required. This ID uniquely
identifies the message in an XMPP connection. The ACK or NACK from CCS uses the
identifies the message in an XMPP connection. The ACK or NACK from CCS uses the
{@code message_id} to identify a message sent from 3rd-party app servers to CCS.
{@code message_id} to identify a message sent from 3rd-party app servers to CCS.
Therefore, it's important that this {@code message_id} not only be unique, but
Therefore, it's important that this {@code message_id} not only be unique (per
always present.</li>
sender ID), but always present.</li>
</ul>
</ul>


<p>In addition to regular GCM messages, control messages are sent, indicated by
<p>In addition to regular GCM messages, control messages are sent, indicated by
@@ -188,7 +189,8 @@ parameters and which connection server(s) supports them.</p>
          &quot;hello&quot;:&quot;world&quot;,
          &quot;hello&quot;:&quot;world&quot;,
      }
      }
      &quot;time_to_live&quot;:&quot;600&quot;,
      &quot;time_to_live&quot;:&quot;600&quot;,
      &quot;delay_while_idle&quot;: true/false
      &quot;delay_while_idle&quot;: true/false,
      &quot;delivery_receipt_requested&quot;: true/false
  }
  }
  &lt;/gcm&gt;
  &lt;/gcm&gt;
&lt;/message&gt;
&lt;/message&gt;
@@ -227,42 +229,48 @@ message is &quot;nack&quot;. A NACK message contains:</p>
<p>Below are some examples.</p>
<p>Below are some examples.</p>


<p>Bad registration:</p>
<p>Bad registration:</p>

<pre>&lt;message&gt;
<pre>&lt;message&gt;
  &lt;data:gcm xmlns:data=&quot;google:mobile:data&quot;&gt;
  &lt;gcm xmlns=&quot;google:mobile:data&quot;&gt;
  {
  {
    &quot;error&quot;:&quot;BAD_REGISTRATION&quot;,  // error code
    &quot;message_type&quot;:&quot;nack&quot;,
    &quot;message_id&quot;:&quot;msgId1&quot;,
    &quot;message_id&quot;:&quot;msgId1&quot;,
    &quot;from&quot;:&quot;PA91bHFOtaQGSwupt5l1og&quot;,
    &quot;from&quot;:&quot;SomeInvalidRegistrationId&quot;,
    &quot;message_type&quot;:&quot;nack&quot;
    &quot;error&quot;:&quot;BAD_REGISTRATION&quot;,
    &quot;error_description&quot;:&quot;Invalid token on 'to' field: SomeInvalidRegistrationId&quot;
  }
  }
  &lt;/data:gcm&gt;
  &lt;/gcm&gt;
&lt;/message&gt;</pre>
&lt;/message&gt;</pre>


<p>Invalid "time to live":</p>
<p>Invalid JSON:</p>


<pre>&lt;message&gt;
<pre>&lt;message&gt;
  &lt;data:gcm xmlns:data=&quot;google:mobile:data&quot;&gt;
 &lt;gcm xmlns=&quot;google:mobile:data&quot;&gt;
 {
 {
     &quot;error&quot;:&quot;InvalidJson : INVALID_TTL : Invalid value (-1) for \&quot;time_to_live\&quot;: must be between 0 and \&quot;2419200\&quot;\n&quot;,
   &quot;message_type&quot;:&quot;nack&quot;,
   &quot;message_id&quot;:&quot;msgId1&quot;,
   &quot;message_id&quot;:&quot;msgId1&quot;,
   &quot;from&quot;:&quot;APA91bHFOtaQGSwupt5l1og&quot;,
   &quot;from&quot;:&quot;APA91bHFOtaQGSwupt5l1og&quot;,
     &quot;message_type&quot;:&quot;nack&quot;
   &quot;error&quot;:&quot;INVALID_JSON&quot;,
   &quot;error_description&quot;:&quot;InvalidJson: JSON_TYPE_ERROR : Field \&quot;time_to_live\&quot; must be a JSON java.lang.Number: abc&quot;
 }
 }
  &lt;/data:gcm&gt;
 &lt;/gcm&gt;
&lt;/message&gt;</pre>
&lt;/message&gt;
</pre>


<p>JSON type error:</p>
<p>Quota exceeded:</p>


<pre>&lt;message&gt;
<pre>&lt;message&gt;
  &lt;data:gcm xmlns:data=&quot;google:mobile:data&quot;&gt;
 &lt;gcm xmlns=&quot;google:mobile:data&quot;&gt;
 {
 {
     &quot;error&quot;:&quot;InvalidJson : JSON_TYPE_ERROR : Field \&quot;delay_while_idle\&quot; must be a JSON java.lang.Boolean: not-boolean-user-supplied-value\n&quot;,
   &quot;message_type&quot;:&quot;nack&quot;,
   &quot;message_id&quot;:&quot;msgId1&quot;,
   &quot;message_id&quot;:&quot;msgId1&quot;,
   &quot;from&quot;:&quot;APA91bHFOtaQGSwupt5l1og&quot;,
   &quot;from&quot;:&quot;APA91bHFOtaQGSwupt5l1og&quot;,
     &quot;message_type&quot;:&quot;nack&quot;
   &quot;error&quot;:&quot;QUOTA_EXCEEDED&quot;,
   &quot;error_description&quot;:&quot;Short-term downstream quota exceeded for this registration id&quot;
 }
 }
  &lt;/data:gcm&gt;
 &lt;/gcm&gt;
&lt;/message&gt;</pre>
&lt;/message&gt;
</pre>




<p>The following table lists NACK error codes. Unless otherwise
<p>The following table lists NACK error codes. Unless otherwise
@@ -300,7 +308,7 @@ message should be immediately retried over another connection.</td>
</tr>
</tr>
<tr>
<tr>
<td>{@code INVALID_JSON}</td>
<td>{@code INVALID_JSON}</td>
<td>The JSON message payload was not valid.</td>
<td>The JSON message payload is not valid.</td>
</tr>
</tr>
<tr>
<tr>
<td>{@code QUOTA_EXCEEDED}</td>
<td>{@code QUOTA_EXCEEDED}</td>
@@ -382,8 +390,8 @@ Bundle data = new Bundle();
// Bundle data consists of a key-value pair
// Bundle data consists of a key-value pair
data.putString("hello", "world");
data.putString("hello", "world");
// "time to live" parameter
// "time to live" parameter
// This is optional. It specifies a value in seconds up to 4 weeks.
// This is optional. It specifies a value in seconds up to 24 hours.
int ttl = [0 seconds, 4 weeks]
int ttl = [0 seconds, 24 hours]


gcm.send(GCM_SENDER_ID + "&#64;gcm.googleapis.com", id, ttl, data);
gcm.send(GCM_SENDER_ID + "&#64;gcm.googleapis.com", id, ttl, data);
</pre>
</pre>
@@ -419,6 +427,69 @@ response to the above message:</p>
  &lt;/gcm&gt;
  &lt;/gcm&gt;
&lt;/message&gt;</pre>
&lt;/message&gt;</pre>


<h3 id="receipts">Receive return receipts</h3>

<p>You can use upstream messaging to get receipt notifications, confirming
that a given message was sent to a device. Your 3rd-party app server receives the receipt
notification from CCS once the message has been sent to the device.</p>

<p>To enable this feature, the message your 3rd-party app server sends to CCS must include
a field called <code>&quot;delivery_receipt_requested&quot;</code>. When this field is set to
<code>true</code>, CCS sends a return receipt. Here is an XMPP stanza containing a JSON
message with <code>&quot;delivery_receipt_requested&quot;</code> set to <code>true</code>:</p>

<pre>&lt;message id=&quot;&quot;&gt;
  &lt;gcm xmlns=&quot;google:mobile:data&quot;&gt;
  {
      &quot;to&quot;:&quot;REGISTRATION_ID&quot;,
      &quot;message_id&quot;:&quot;m-1366082849205&quot;
      &quot;data&quot;:
      {
          &quot;hello&quot;:&quot;world&quot;,
      }
      &quot;time_to_live&quot;:&quot;600&quot;,
      &quot;delay_while_idle&quot;: true,
      <strong>&quot;delivery_receipt_requested&quot;: true</strong>
  }
  &lt;/gcm&gt;
&lt;/message&gt;
</pre>

<p>Here is an example of a receipt notification message that CCS sends back to your 3rd-party
app server:</p>

</p>
<pre>&lt;message id=&quot;&quot;&gt;
  &lt;gcm xmlns=&quot;google:mobile:data&quot;&gt;
  {
      &quot;category&quot;:&quot;com.example.yourapp&quot;, // to know which app sent it
      &quot;data&quot;:
      {
         &#x201c;message_status&quot;:&quot;MESSAGE_SENT_TO_DEVICE&quot;,
         &#x201c;original_message_id&#x201d;:&#x201d;m-1366082849205&#x201d;
         &#x201c;device_registration_id&#x201d;: &#x201c;REGISTRATION_ID&#x201d;
      },
      &quot;message_id&quot;:&quot;dr2:m-1366082849205&quot;,
      &quot;message_type&quot;:&quot;receipt&quot;,
      &quot;from&quot;:&quot;gcm.googleapis.com&quot;
  }
  &lt;/gcm&gt;
&lt;/message&gt;</pre>

<p>Note the following:</p>

<ul>
  <li>The {@code &quot;message_type&quot;} is set to {@code &quot;receipt&quot;}.
  <li>The {@code &quot;message_status&quot;} is set to {@code &quot;MESSAGE_SENT_TO_DEVICE&quot;},
  indicating that the message was delivered. Notice that in this case,
{@code &quot;message_status&quot;} is not a field but rather part of the data payload.</li>
  <li>The receipt message ID consists of the original message ID, but with a
<code>dr:</code> prefix. Your 3rd-party app server must send an ACK back with this ID,
which in this example is {@code dr2:m-1366082849205}.</li>
  <li>The original message ID and status are inside the
{@code &quot;data&quot;} field.</li>
</ul>

<h2 id="flow">Flow Control</h2>
<h2 id="flow">Flow Control</h2>


<p>Every message sent to CCS receives either an ACK or a NACK response. Messages
<p>Every message sent to CCS receives either an ACK or a NACK response. Messages
+2 −1
Original line number Original line Diff line number Diff line
@@ -246,7 +246,8 @@ private boolean checkPlayServices() {
<h3 id="sample-register">Register for GCM</h3>
<h3 id="sample-register">Register for GCM</h3>
<p>An Android application needs to register with GCM servers before it can receive
<p>An Android application needs to register with GCM servers before it can receive
messages. When an app registers, it receives a registration ID, which it can then
messages. When an app registers, it receives a registration ID, which it can then
store for future use. In the following snippet the {@code onCreate()} method in the sample app's
store for future use (note that registration IDs must be kept secret). In the
following snippet the {@code onCreate()} method in the sample app's
main activity checks to see if the app is already registered with GCM and with
main activity checks to see if the app is already registered with GCM and with
the server:</p>
the server:</p>


+1 −1
Original line number Original line Diff line number Diff line
@@ -123,7 +123,7 @@ it to receive messages. Once the Android application has the registration ID, it
it to the 3rd-party application server, which uses it to identify each device 
it to the 3rd-party application server, which uses it to identify each device 
that has registered to receive messages for a given Android application. In other words,
that has registered to receive messages for a given Android application. In other words,
a registration ID is tied to a particular Android application running on a particular
a registration ID is tied to a particular Android application running on a particular
device.
device. Note that registration IDs must be kept secret.
<br/>
<br/>
<br/>
<br/>
<strong>Note:</strong> If you use 
<strong>Note:</strong> If you use 
+25 −14
Original line number Original line Diff line number Diff line
@@ -14,7 +14,10 @@ header.hide=1
  <h1 itemprop="name" style="margin-bottom:0;">Google Cloud Messaging for Android</h1>
  <h1 itemprop="name" style="margin-bottom:0;">Google Cloud Messaging for Android</h1>
  <p itemprop="description">
  <p itemprop="description">
  Google Cloud Messaging for Android (GCM) is a service that allows you to send data
  Google Cloud Messaging for Android (GCM) is a service that allows you to send data
from your server to your users' Android-powered device, and also to receive messages from devices on the same connection. The GCM service handles all aspects of queueing of messages and delivery to the target Android application running on the target device. GCM is completely free no matter how big your messaging needs are, and there are no quotas.
from your server to your users' Android-powered device, and also to receive messages from
devices on the same connection. The GCM service handles all aspects of queueing of messages
and delivery to the target Android application running on the target device. GCM is
completely free no matter how big your messaging needs are, and there are no quotas.
</p>
</p>


</div>
</div>
@@ -27,31 +30,39 @@ from your server to your users' Android-powered device, and also to receive mess
    <p>This could be a lightweight
    <p>This could be a lightweight
message telling your app there is new data to be fetched from the
message telling your app there is new data to be fetched from the
server (for instance, a movie uploaded by a friend), or it could be a message containing
server (for instance, a movie uploaded by a friend), or it could be a message containing
up to 4kb of payload data (so apps like instant messaging can consume the message directly). <a href="{@docRoot}google/gcm/gcm.html">GCM Architectural Overview.</a></p>
up to 4kb of payload data (so apps like instant messaging can consume the message directly).
<a href="{@docRoot}google/gcm/gcm.html">GCM Architectural Overview.</a></p>


    <h4>Send "send-to-sync" messages</h4>
    <h4>Send "send-to-sync" messages</h4>
    <p>A send-to-sync (collapsible) message is often a "tickle" that tells a mobile application to sync data from the server. For example, suppose you have an email application. When a user receives new email on the server, the server pings the mobile application with a "New mail" message. This tells the application to sync to the server to pick up the new email.
    <p>A send-to-sync (collapsible) message is often a "tickle" that tells a mobile
    <a href="{@docRoot}google/gcm/adv.html#s2s">Send-to-sync messages</a>.</p>
    application to sync data from the server. For example, suppose you have an email
    </a>
    application. When a user receives new email on the server, the server pings the mobile
    application with a "New mail" message. This tells the application to sync to the server
    to pick up the new email.
    <a href="{@docRoot}google/gcm/adv.html#s2s">Learn more &raquo;</a></p>


    <h4>Send messages with payload</h4>
    <h4>Send messages with payload</h4>
    <p>Unlike a send-to-sync message, every "message with payload" (non-collapsible message) is delivered. The payload the message contains can be up to 4kb.
    <p>Unlike a send-to-sync message, every "message with payload" (non-collapsible message)
    <a href="{@docRoot}google/gcm/adv.html#payload">Messages with payload</a>.</p>
    is delivered. The payload the message contains can be up to 4kb.
    <a href="{@docRoot}google/gcm/adv.html#payload">Learn more &raquo;</a></p>
  </div>
  </div>




  <div class="col-6 normal-links">
  <div class="col-6 normal-links">
    <h3 style="clear:left">New Features</h3>
    <h3 style="clear:left">New Features</h3>
    <h4>Faster, easier GCM setup</h4>
    <p>Streamlined registration makes it simple and fast to add GCM support to your Android app. <a href="{@docRoot}google/gcm/gs.html">Learn more &raquo;</a></p>
    <h4>Upstream messaging over XMPP</h4>
    <p>GCM's Cloud Connection Service (CCS) lets you communicate with Android devices over a persistent XMPP connection. The primary advantages of CCS are speed, and the ability to receive upstream messages (that is, messages from a device to the cloud). You can use the service in tandem with existing GCM APIs. Use <a href="https://services.google.com/fb/forms/gcm/">this form</a> to sign up for CCS. <a href="{@docRoot}google/gcm/ccs.html">Learn more &raquo;</a></p>


    <h4>Seamless multi-device messaging</h4>

    <p>Maps a single user to a notification key, which you can then use to send a single message to multiple devices owned by the user. Use <a href="https://services.google.com/fb/forms/gcm/">this form</a> to sign up for User Notifications. <a href="{@docRoot}google/gcm/notifications.html">Learn more &raquo;</a></p>

    <h4>Return Receipts</h4>
    <p>You can use upstream messaging to get receipt notifications, confirming that a given
    message was sent to a device. Your 3rd-party app server receives the receipt notification
    from CCS once the message has been sent to the device.
    <a href="{@docRoot}google/gcm/ccs.html#receipts">Learn more &raquo;</a></p>



   <h4>Get Started</h4>
   <h4>Get Started</h4>
    <p>Get started using the new features with a tutorial that walks you through creating a GCM app. <a href="{@docRoot}google/gcm/gs.html">Learn more &raquo;</a></p>
    <p>Get started with a tutorial that walks you through creating a GCM app.
    <a href="{@docRoot}google/gcm/gs.html">Learn more &raquo;</a></p>
  </div>
  </div>


</div>
</div>
+110 −19
Original line number Original line Diff line number Diff line
@@ -14,8 +14,8 @@ page.title=User Notifications
<h2>In this document</h2>
<h2>In this document</h2>


<ol class="toc">
<ol class="toc">
  <li><a href="#request">Request Format</a></li>
  <li><a href="#gen-server">Generate a Notification Key on the Server</a></li>
  <li><a href="#create">Generate a Notification Key</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="#add">Add Registration IDs</a></li>
  <li><a href="#remove">Remove 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="#upstream">Send Upstream Messages</a></li>
@@ -31,15 +31,11 @@ page.title=User Notifications


<ol class="toc">
<ol class="toc">
<li><a href="{@docRoot}google/gcm/gs.html">Getting Started</a></li>
<li><a href="{@docRoot}google/gcm/gs.html">Getting Started</a></li>
<li><a href="https://services.google.com/fb/forms/gcm/" class="external-link" target="_android">CCS and User Notifications Signup Form</a></li>
</ol>
</ol>


</div>
</div>
</div>
</div>


<p class="note"><strong>Note:</strong> To try out this feature, sign up using <a href="https://services.google.com/fb/forms/gcm/">this form</a>.</p>


<p>With user notifications, 3rd-party app servers can send a single message to
<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
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
is called <em>user notifications</em>. User notifications make it possible for every
@@ -76,27 +72,23 @@ and then reconciling it with the corresponding notification.
<p>You can use this feature with either the <a href="ccs.html">XMPP</a> (CCS) or
<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>
<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,
<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
and how to send upstream messages. For generate/add/remove operations, the
message body is JSON.</p>
message body is JSON.</p>


<h2 id="request">Request Format</h2>
<h2 id="gen-server">Generate a Notification Key on the Server</h2>
<p>To send a  message, 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 create/add/remove operations:</p>
<p>To generate a notification key on the server, you create a new

create a new <code>notification_key</code> and map it to a
<pre>content-type: "application/json"
<code>notification_key_name</code>.</p>
Header : "project_id": &lt;projectID&gt;
Header: "Authorization", "key=API_KEY"
</pre>

<h2 id="create">Generate a Notification Key</h2>


<p>This example shows how to create a new <code>notification_key</code> for a
<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>.
<code>notification_key_name</code> called <code>appUser-Chris</code>.
The {@code notification_key_name} is a name or identifier (can be a username for
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
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>
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
and <code>notification_key</code> are unique to a group of registration IDs. It is also
@@ -116,10 +108,109 @@ to use in subsequent operations:</p>
   &quot;registration_ids&quot;: [&quot;4&quot;, &quot;8&quot;, &quot;15&quot;, &quot;16&quot;, &quot;23&quot;, &quot;42&quot;]
   &quot;registration_ids&quot;: [&quot;4&quot;, &quot;8&quot;, &quot;15&quot;, &quot;16&quot;, &quot;23&quot;, &quot;42&quot;]
}</pre>
}</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": &lt;projectID&gt;
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 &amp; AUTH &gt; 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 &gt; 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(&quot;com.google&quot;);
    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 = &quot;audience:server:client_id:&quot;
        + &quot;1262xxx48712-9qs6n32447mcj9dirtnkyrejt82saa52.apps.googleusercontent.com&quot;;
String id_token = null;
try {
    id_token = GoogleAuthUtil.getToken(context, accountName, scope);
} catch (Exception e) {
    log(&quot;exception while getting id_token: &quot; + 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:
{
   &quot;operation&quot;: &quot;add&quot;,
   &quot;notification_key_name&quot;: &quot;appUser-Chris&quot;,
   &quot;registration_ids&quot;: [&quot;4&quot;]
   &quot;id_token&quot;: &quot;id_token&quot;
}</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": &lt;projectID&gt;
</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>
<h2 id="add">Add Registration IDs</h2>


<p>This example shows how to add registration IDs for a given notification key.
<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 10.</p>
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
<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
adding/removing regIDs. But including it protects you against accidentally using
Loading