Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

With Android GCM, can you use a deep JSON 'data' field?

That is, can you send

{
  "registration_ids": ["whatever", ...],
  "data": {
    "foo": {
      "bar": {
        "baz": [42]
      }
    }
  }
}

or is the "data" member of the GCM request restricted to one level of key-value pairs? I ask b/c that limitation is suggested by the wording in Google's doc[1], where it says "data" is:

A JSON object whose fields represents the key-value pairs of the message's payload data. If present, the payload data it will be included in the Intent as application data, with the key being the extra's name. For instance, "data":{"score":"3x1"} would result in an intent extra named score whose value is the string 3x1 There is no limit on the number of key/value pairs, though there is a limit on the total size of the message. Optional.

[1] http://developer.android.com/guide/google/gcm/gcm.html#request

like image 201
Rob Starling Avatar asked Jul 07 '12 19:07

Rob Starling


2 Answers

Just did a test myself and confirmed my conjecture.

Send a GCM to myself with this payload:

{
  "registration_ids": ["whatever", ...],
  "data": {
     "message": {
        "bar": {
           "baz": [42]
        }
     }
  }
}

And my client received it and parse the 'message' intent extra as this:

handleMessage - message={        "bar": {          "baz": [42]        }      }  

So the you can indeed do further JSON parsing on the value of a data key.

like image 186
azgolfer Avatar answered Sep 28 '22 06:09

azgolfer


Although it appears to work (see other answers and comments), without a clear statement from Google, i would not recommend relying on it as their documentation consistently refers to the top-level members of the json as "key-value pairs". The server-side helper jar they provide [1] also reinforces this idea, as it models the user data as a Map<String, String>. Their Message.Builder.addData method doesn't even support non-string values, so even though booleans, numbers, and null are representable in json, i'd be cautious using those, too.

If Google updates their backend code in a way that breaks this (arguably-unsupported) usage, apps that relied on it would need an update to continue to work. In order to be safe, i'm going to be using a single key-value pair whose value is a json-stringified deep object [2]. My data isn't very big, and i can afford the json-inside-json overhead, but ymmv. Also, one of my members is a variable-length list, and flattening those to key-value pairs is always ugly :)

[1] http://developer.android.com/guide/google/gcm/server-javadoc/index.html (The jar itself is only available from within the Android SDK in the gcm-server/dist directory, per http://developer.android.com/guide/google/gcm/gs.html#server-app )

[2] e.g. my whole payload will look something like this:

{
  "registration_ids": ["whatever", ...],
  "data": {
    "player": "{\"score\": 1234, \"new_achievements\": [\"hot foot\", \"nimble\"]}"
  }
}
like image 36
Rob Starling Avatar answered Sep 28 '22 06:09

Rob Starling