Sorry, you need to enable JavaScript to visit this website.

Android Mobile Push Gateway Tutorial for Realtime Apps

 
Requires that the Push Notifications add-on is enabled for your key. How do I enable add-on features for my keys? - see http://www.pubnub.com/knowledge-base/discussion/644/how-do-i-enable-add-on-features-for-my-keys
PubNub’s Mobile Push Gateway feature enables developers to bridge native PubNub publishing with 3rd-party push notification services including Google Android GCM (Google Cloud Messaging), Apple iOS APNS (Apple Push Notification Service), and Microsoft Windows Phone MPNS (Microsoft Push Notification Service).

By using the Mobile Push Gateway, developers can eliminate the need for developing, configuring, and maintaining additional server-side components for 3rd-party push notification providers.
For mission critical messaging, PubNub recommends implementing PubNub native messaging functionality. PubNub native messaging touts a low-latency, bi-directional notification solution that can be delivered to any mobile device, secure, access restricted, and encrypted message payloads of up to 32KB, and the ability to recover missed messages with Storage & Playback (history) APIs.

Despite the advantages of the native PubNub approach, there are cases where a developer may choose to utilize a 3rd-party notification system, for example, when migrating existing applications already utilizing 3rd-party notification systems to PubNub native messaging. On iOS, Android, and Windows applications where running in the background is not an option, the Mobile Push Gateway provides a method to send messages quickly and reliably via PubNub whether or not the application is in the foreground or background.
Native PubNub Publish and Subscribe operation dictates that when a message is published by a client on a specific channel, all clients subscribing to that channel will receive that message.

When the Mobile Push Gateway is enabled, you may associate unique mobile devices (via their device push tokens) with PubNub channel names.  Once this association is made, when a message is published to a channel that has been associated with an GCM, APNS, or MPNS device, all associated GCM, APNS, or MPNS devices will receive that message via their associated (GCM, APNS, or MPNS) native service.

Behind the scenes, the PubNub Mobile Push Gateway establishes an authenticated connection to GCM, APNS, or MPNS service providers based on your registered configuration.
Before you can use PubNub Mobile Push Gateway with GCM, you must first setup your GCM configuration.
  1. Download the Google Play services SDK - http://developer.android.com/tools/help/sdk-manager.html
  2. Set Up Google Play Services SDK - http://developer.android.com/google/play-services/setup.html
  3. Create a Google API project - http://developer.android.com/google/gcm/gs.html#create-proj
  4. Enable the GCM Service - http://developer.android.com/google/gcm/gs.html#gcm-service
  5. Obtain an Google API Key - http://developer.android.com/google/gcm/gs.html#access-key
  6. Once you’ve obtained the API Key, login to the PubNub Admin Console, and scroll down to Push Notifications → Google Cloud Messaging and click on "Add" to add your API Key.
http://developer.android.com/google/gcm/gs.html provides general information about the Google-side of this process.
To register for receipt of messages arriving on a PubNub channel to be forwarded to an Android device via GCM, you must first retrieve that Android device’s unique ID, otherwise know as its registration token.
The following instructions taken directly from here, demonstrate how to retrieve an Android registration token:
  1. An Android application needs to register with GCM connection servers before it can receive messages.
  2. When an app registers, it receives a registration token and sends it to the app server. The client app should store a boolean value indicating whether the registration token has been sent to the server.
  3. Google provides the Instance ID API to handle the creation and updating of registration tokens. To obtain a token, call instanceID.getToken, providing the app server's sender ID and setting the scope to GoogleCloudMessaging.INSTANCE_ID_SCOPE.
    Do not call this method in the main thread; instead, use a service that extends IntentService as shown:
    InstanceID instanceID = InstanceID.getInstance(this);
    String token = instanceID.getToken(getString(R.string.gcm_defaultSenderId),
            GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
    
  4. Once you've received your registration token, make sure to send it to your server as shown.
    The listener service's onTokenRefresh method should be invoked if the GCM registration token has been refreshed:
    @Override
    public void onTokenRefresh() {
        // Fetch updated Instance ID token and notify our app's server of any changes (if applicable).
        Intent intent = new Intent(this, RegistrationIntentService.class);
        startService(intent);
    }
    
  5. Once onTokenRefresh is called, use InstanceID.getToken() to get a new registration token, and then send the new token to your app server. See the Instance ID API reference for full detail on this API.
Once you have successfully retrieved your registration token and associated it with PubNub channels, before you can receive any GCM messages, you must implement the GcmListenerService.onMessageReceived method.
The following instructions taken directly from https://developers.google.com/cloud-messaging/android/client demonstrate how to implement the GcmListenerService.onMessageReceived method:
  • To receive simple downstream messages, use a service that extends GcmListenerService to handle messages captured by GcmReceiver.GcmReceiver extends WakefulBroadcastReceiver, guaranteeing that the CPU is awake so that your listener service can complete its task.
  • By overriding the method GcmListenerService.onMessageReceived, you can perform actions based on the received message.
    
    @Override
    public void onMessageReceived(String from, Bundle data) {
        String message = data.getString("message");
        Log.d(TAG, "From: " + from);
        Log.d(TAG, "Message: " + message);
    
        /**
         * Production applications would usually process the message here.
         * Eg: - Syncing with server.
         *     - Store message in local database.
         *     - Update UI.
         */
    
        /**
         * In some cases it may be useful to show a notification indicating to the user
         * that a message was received.
         */
        sendNotification(message);
    
    
enablePushNotificationsOnChannel and its variant methods associate a channel to a registration token.
pubnub.enablePushNotificationsOnChannel(channel, registrationToken, new Callback(){

    @Override

    public void successCallback(String channel, Object response) {

    }

    @Override

    public void errorCallback(String channel, PubnubError error) {


    }
});
disablePushNotificationsOnChannel and its variant methods associate a channel to a registration token.
pubnub.disablePushNotificationsOnChannel(channel, registrationToken, new Callback(){

    @Override

    public void successCallback(String channel, Object response) {

    }

    @Override

    public void errorCallback(String channel, PubnubError error) {


    }
});
requestPushNotificationEnabledChannelsForDeviceRegistrationId lists channels registered to device token.
pubnub.requestPushNotificationEnabledChannelsForDeviceRegistrationId(registrationToken, new Callback(){

    @Override

    public void successCallback(String channel, Object response) {

    }

    @Override

    public void errorCallback(String channel, PubnubError error) {


    }
});
The equivalent method calls are also available via our Javascript, Android, Objective-C, Swift, and .NET Mobile Gateway guides.
PubNub SDKs natively support associating device/registration tokens to channel names. To achieve this, they use a REST wrapper to add, remove, and list device registration IDs by channel.
The following serves as a REST request reference for adding, removing, and listing associated devices and channels. Whenever possible, use the native method call available in the SDK, instead of manually issuing the REST call.
http://pubsub.pubnub.com/v1/push/sub-key/<SUB_KEY>/devices/<REG_ID>?<OPERATION>=<CHANNEL_LIST>&type=<TYPE>
Parameter Type Required Description
OPERATION AND CHANNEL_LIST
OPERATION is one of add, list or remove. CHANNEL_LIST is a comma separated string of channels.
Optional
If not specified, defaults to the the list operation.
SUB_KEY
String
Yes
This is your PN API Subscribe key.
REG_ID
string
Yes
The device registraton ID.
TYPE
TYPE is one of gcm, apns, and mpns.
Optional
If no type specified, server will default to apns (for backwards compatibility)

[1, "Modified Channels"]
  • On success returns a 200 JSON Array of [1, "Modified Channels"].
  • On error returns 403 for PAM errors. Any status code other than 200 or 403 should be handled as fatal and retried at your discretion.
http://pubsub.pubnub.com/v1/push/sub-key/demo/devices/ALICE?type=gcm | apns | mpns &add=myCH
http://pubsub.pubnub.com/v1/push/sub-key/demo/devices/ALICE?type=gcm | apns | mpns&add=news,sports
http://pubsub.pubnub.com/v1/push/sub-key/demo/devices/ALICE?type=gcm | apns | mpns
http://pubsub.pubnub.com/v1/push/sub-key/demo/devices/ALICE?type=gcm | apns | mpns&remove=myCH
http://pubsub.pubnub.com/v1/push/sub-key/demo/devices/ALICE/remove?type=gcm | apns | mpns
Using a stock trading app use-case as an example, you may wish to send this stock alert to your users:
{
	"name": "Fitchwitz Technology",
	"snapshot": {
   		"last": 40.52,
   		"volume": "3495345",
   		"change": ["+4.02","+7.45%"]
	},
	"ticker": {
   	"newsflash": [
       	"Fitchwitz antivirals in the total number of shares being sold in the public offering have exercised in full.",
       	"The offering price of all their option to purchase an additional zillion shares of its common stock is sweet.",
       	"Offering is expected to occur today announced public offering when 100 shares went byebye."
   	],
   	"url": "http://FitchwitzTech.com/fooz"
	}
}
This message is received, in its entirety, to all native PubNub client subscribers.
To make it properly formatted for receipt via GCM, we must add a pn_gcm.data attribute to it, like so:
{
	"name": "Fitchwitz Technology",
	"pn_gcm": {
   	"data": {
          "title_for_mobile": "Fitchwitz Technology",
          "summary_for_mobile": [ "Fitchwitz antivirals... more info at http://FitchwitzTech.com/fooz" ]
   	}
	},
	"snapshot": {
   		"last": 40.52,
   		"volume": "3495345",
   		"change": ["+4.02","+7.45%"]
	},
	"ticker": {
   	"newsflash": [
       	"Fitchwitz antivirals in the total number of shares being sold in the public offering have exercised in full.",
       	"The offering price of all their option to purchase an additional zillion shares of its common stock is sweet.",
       	"Offering is expected to occur today announced public offering the offering when 100 shares went byebye."
   	],
   	"url": "http://FitchwitzTech.com/fooz"
	}
}
 
pn_gcm.data must contain a dictionary of keys and values. pn_gcm.data cannot be a string, int, or array.
After making these modifications to our message payload, upon publishing, this message will still be received in its entirety by all native PubNub client subscribers (including any pn_gcm, pn_apns, and pn_mpns contents), however, any devices registered to receive messages on the published channel via GCM, APNS, or MPNS will only receive the content contained within pn_gcm, pn_apns, or pn_mpns, respectively.
The following examples show how to publish to GCM devices with the PubNub Java client:
// Create GCM Message

PnGcmMessage gcmMessage = new PnGcmMessage();


// Create the payload and set data for GCM message

JSONObject jso = new JSONObject();

try {

    jso.put("a", "1");

} catch (JSONException e) {

}


gcmMessage.setData(jso);



// Create APNS message

PnApnsMessage apnsMessage = new PnApnsMessage();


apnsMessage.setApsAlert("hi");

apnsMessage.setApnsBadge(2);

apnsMessage.setSound("melody");


apnsMessage.put("c", "3");



String channel = "demo";



// Create PnMessage

PnMessage message = new PnMessage(pubnub, channel, new Callback(){

    @Override

    public void successCallback(String channel, Object response) {

        System.out.println(response);
    
    }


    @Override

    public void errorCallback(String channel, PubnubError error) {

        System.out.println(error);

    }
}, apnsMessage, gcmMessage);



message.put("b", "2");



try {

    message.publish();

} catch (PubnubException e) {

}
The JSON message published by the above looks would be:
   "pn_apns": {

        "aps" : { 

            "alert": "hi",

            "badge": 2,

            "sound": "melody"

        },

        "c" : "3"

    },

    "pn_gcm": {

        "data" : {

	    "a" : "1"

        }

    },

    "b" : "2"

}
Publishing using the above referenced dictionary structure, or via the literal JSON snippet, both have the same effect.
If you are interested in sending unique messages on a per-Mobile Gateway type in a single publish, just include all or some additional endpoint key (pn_apns, pn_gcm and pn_mpns) in your message:
Native PubNub devices will receive the ENTIRE message payload, but 3rd-Party endpoints by type will only receive the data encapsulated in their associated endpoint key.
In the below example:
  • Associated APNS devices will receive only the data within the pn_apns key.
  • Associated GCM devices will receive only the data within the pn_gcm key.
  • Associated MPNS devices will receive only the data within the pn_mpns key.
  • Native PubNub subscribers will receive the entire object literal, including the pn_apns, pn_gcm, pn_mpns, and full_game keys.
{

    "pn_apns": {

        "aps" : {

            "alert": "Game update 49ers touchdown",

            "badge": 2

        },

        "teams" : ["49ers", "raiders"],

        "score" : [7, 0]

    },

    "pn_gcm": {

        "data" : {

            "summary": "Game update 49ers touchdown",

            "teams" : ["49ers", "raiders"],

            "score" : [7, 0],

            "lastplay" : "5yd run up the middle"
    
        }

    },

    "pn_mpns" : {

        "type" : "flip",

        "title" : "Front title",

        "count" : 1,

        "back_title" : "Back Tile",

        "back_content" : "Back message"

    },

    "full_game" : {

        "date" : "2014.05.20",

        "foobar" : "Data that is not pertinent to devices"

    }

}
For any given published message, you may include any combination of pn_* and non-pn_* keys and data.
 
If a device has been registered to receive Mobile Push Gateway messages via GCM, APNS, or MPNS, and is also running a native PubNub Android, iOS, or Windows client SDK, and is natively subscribed to the same associated channel via the native PubNub client SDK, it will receive the message twice -- once via the Mobile Push Gateway, and once via the native PubNub client SDK. You will need to manually add logic to de-duplicate in this case.
If you are experiencing issues publishing to devices via the PubNub Mobile Gateway, the following are debug techniques that may help narrow down the issue. Each of them circumvents PubNub’s Mobile Push Gateway logic to ensure that your device push tokens, applications, and registration/certificates are configured correctly.
If the following scripts are not working for you, then PubNub isn’t a variable in the cause of the issue -- successful results with the below scripts script is a pre-requisite for PubNub Mobile Gatway logic to work.  Regardless if its a PubNub issue or not, we’re always happy to help!  By getting us the results of the following tests when opening a support ticket, it may save a lot time isolating the root cause of your issue.
Use this script to publish a message to APNS, completely circumventing PubNub infrastructure. It requires an APNS certificate and an iOS device token.
Use the following curl command to publish a message to GCM, completely circumventing PubNub infrastructure. It requires a registration ID. Taken from Google’s GCM page.
curl --header "Authorization: key=<API_KEY>" \

    --header Content-Type:"application/json" \

    https://gcm-http.googleapis.com/gcm/send \

    -d "{\"registration_ids\":[\"ABC\"]}"
Use the following curl command to publish a message to MPNS, completely circumventing PubNub infrastructure. It requires a device push token.
curl -v -H "Content-Type:text/xml" -H "X-WindowsPhone-Target:Toast" -H "X-NotificationClass:2" -X POST -d "<?xml version='1.0' encoding='utf-8'?><wp:Notification xmlns:wp='WPNotification'><wp:Toast><wp:Text1>My title</wp:Text1><wp:Text2>My subtitle</wp:Text2></wp:Toast></wp:Notification>" http://dm2.notify.live.net/throttledthirdparty/01.00/AQGiZ6EjjX0ySLELCr3iykPvAgAAAAADBAAAAAQUZm52OkRFNzg2NTMxMzlFMEZFNkMFBlVTU0MwMQ
You can enable more debug logging by included a flag in the publish payload. Any debug returned by the service published to a specide debug channel.
  1. Include "pn_debug" : true in your Mobile Gateway message payload.  This will require you to send the raw JSON yourself, and not rely on any convienence methods that create the Mobile Gateway message payload programatically for you. For example, to troubleshoot APNS issues, you could publish the below literal JSON via the PubNub Developer Console on the channel you desire:
    {
     "pn_apns": {
      "aps": {
       "alert": "Game update 49ers touchdown",
       "badge": 2
      }
     },
     "pn_debug": true
    }
    
  2. Subscribe to <channel>-pndebug to receive any advanced debug information.  For example, if in step 1 you published on channel myCH, you would subscribe using another developer console to myCH-pndebug.
Example messages may include, but are not limited to:
  • "Devices found for ['mpns'] push notification"
  • "Invalid APNS notification format"
  • "Invalid GCM notification format"
For additional platform and endpoint information, please see our detailed Javascript, Android, Objective-C, Swift, and .NET Mobile Gateway guides.

Check out PubNub's other Java-based SDKs, such as Java, Android, Blackberry, CodenameOne, GWT, J2ME, Scala.