PhoneGapPhoneGapNode.jsReact V4WebJavaScriptPhoneGap V4 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)/FCM (Firebase 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/FCM, APNS, or MPNS device, all associated GCM/FCM, APNS, or MPNS devices will receive that message via their associated (GCM/FCM, APNS, or MPNS) native service.

Behind the scenes, the PubNub Mobile Push Gateway establishes an authenticated connection to GCM/FCM, APNS, or MPNS service providers based on your registered configuration.

Device Connected
[currently subscribed]
Device Token/ID
Registered to Channel
Device Token/ID
Not Registered to Channel
App in ForegroundApp in BackgroundApp in ForegroundApp in Background
  • Receive Publish Directly
  • Push Notification Sent
  • Receive Push Notification
    Content [no UI notification]
[Android Only]
  • Receive Publish Directly
  • Push Notification Sent
  • Push Notification Received
    [with UI Notification]

[iOS]
  • Publish Not Received
  • Push Notification Sent
  • Push Notification Received
    [with UI Notification]
  • Receive Publish Directly
  • No Push Notification sent for this device
[Android Only]
  • Receive Publish Directly if subscribed in background
  • No Push Notification sent for this device

[iOS]
  • Publish Not Received
  • No Push Notification sent for this device
Device Disconnected
[not currently subscribed]
Device Token/ID
Registered to Channel
Device Token/ID
Not Registered to Channel
App in ForegroundApp in BackgroundApp in ForegroundApp in Background
  • Publish Not Received
  • Push Notification Sent
  • Receive Push Notification
    Content [no UI notification]
  • Publish Not Received
  • Push Notification Sent
  • Push Notification Received
    [with UI Notification]
  • Publish Not Received
  • No Push Notification sent for this device
  • Publish Not Received
  • No Push Notification sent for this device
 

FCM is just a rebranding of GCM and there is no function difference to handle it in PubNub. The PubNub server's still expect a pn_gcm as part of the payload.

Please check this link to migrate an existing GCM client app on Android to Firebase Cloud Messaging (FCM).

Before you can use PubNub Mobile Push Gateway with GCM/FCM, you must first setup your GCM/FCM 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 project - https://console.firebase.google.com
  4. Select APIs for the project - https://firebase.google.com/docs/cloud-messaging
  5. Get credentials - https://firebase.google.com/docs/cloud-messaging/concept-options#credentials
  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.
https://firebase.google.com/docs/cloud-messaging/server provides general information about the Google-side of this process.
Before you can use PubNub Mobile Push Gateway with MPNS, you must first setup your Windows Phone 8 app to receive push notifications from Microsoft MPNS.
  1. Create a new pubnub key or use an existing account
  2. Add the Push Notifications feature on the key’s portal page.
  3. In Windows Phone 8 app project, enable ID_CAP_PUSH_NOTIFICATION capability in WMAppManifest.xml file located under Properties folder.
  4. To use authenticated push notifications, set C# Pubnub SDK client instance property:pubnub.PushServiceName = "<Your SSL Certificate's Subject Name>";
    Please have a look at the docs from Microsoft here and here for more information about setting up authenticated push notifications.
  5. Set up appropriate notification channel name. In your code, open a notification channel if it does not exist, else connect to existing notification channel name (MS docs indicate one name per app):
    //Sample code snippet :
    string microsoftChannelName = "pushSampleChannel";
    HttpNotificationChannel microsoftPushChannel = HttpNotificationChannel.Find(microsoftChannelName);
    if (microsoftPushChannel == null){
    	if (!string.IsNullOrEmpty(pubnub.PushServiceName)){
    		microsoftPushChannel = new HttpNotificationChannel(microsoftChannelName, pubnub.PushServiceName);
    	}
    	else{
    		microsoftPushChannel = new HttpNotificationChannel(microsoftChannelName);
    	}
    
    	// Register for all the events before attempting to open the channel.
    	.....
    	.....
    
    	microsoftPushChannel.Open();
    
    }
    
  6. To receive the toast notifications while the application is running, register for the ShellToastNotificationReceived event.
    microsoftPushChannel.ShellToastNotificationReceived += new EventHandler<NotificationEventArgs>(PushChannel_ShellToastNotificationReceived);
    
  7. To receive toast notifications, bind the notification channel by calling the BindToShellToast() method.
    microsoftPushChannel.BindToShellToast();
    
  8. To receive tile notifications, bind the notification channel by calling the BindToShellTile() method to access local resources on the device.
    microsoftPushChannel.BindToShellTile(pubnub.PushRemoteImageDomainUri);
    
  9. Register ChannelUriUpdated event before opening notification channel. App should re-register in case push notification URI changes.
Visit MSDN to learn more about MPNS setup and logic to send and receive push notifications.

Apple Push Notification Service (APNs) is the via where is propagated remote notifications to iOS Apps in order to notify that something has happened through an alert when these are running in background, the app is not active in the foreground or the device is offline.

Requirements for this demo:

  1. A PubNub account, if you do not have one you can get one free.
  2. An Apple developer membership.
  3. PhoneGap SDK.
  4. XCode.
  5. An iPhone or iPad device.

In order to use APN we must have a physical device because the security architecture of two levels of trust required for cryptographic validation and authentication between the provider (whom send the notification) to APNs and APNs to device (whom receive the notification) both sides need a trust connection. Each device has a cryptographic certificate and a private cryptographic key provided by the system operative when this is activated. Any emulator contains any of these parts then you cannot get to work this feature at less you do not use a physical device for executing this feature.

For more information about APNs you can visit APN overview.

For this demo we are going to follow the next flow:

  1. An App requests iOS for push notification.
  2. iOS sends the request to APNs.
  3. APNs sends back a device token.
  4. The client app sends the toke to the 3rd party server (in this case, you don't need your own server because you are going to use PubNub network!) To send a push notification:
  5. The server (well, PubNub!) sends a payload to APNs with the token.
  6. APNs sends a push notification to the device.

Using Apple PushNotification

  1. Follow this for valid APNS provisioning on iOS as of iOS 9 and Xcode 7.

    1. Open Keychain Access on your Mac.
    2. In top bar of Finder, select Keychain Access > Certificate Assistant > Request a Certificate From a Certificate Authority.

      Certificate Authority

    3. Fill in your email address and name on the following screen. Make sure to leave the CA email address blank and select Saved to disk.

      Certificate Information

    4. Click continue and save to desktop.

      Certificate Assistant

    5. First open your project and navigate to general settings and build information for your project. Click on Capabilities.

      General Settings

    6. Toggle the switch for Push Notifications to On.

      Switch for Push Notifications

    7. Now we need to add your Push Certificate to your Apple Developer Account on the Developer Portal. Go to this address: https://developer.apple.com/account/.
    8. On the left, under Identifiers, click on App IDs. Then select your app, which should be prepended with something along the lines of Xcode iOS App ID [bundle identifier]. Open this and click Edit at the bottom.

      Bundle Identifier

    9. Now scroll down and make sure to select the box for Push Notifications and click Create Certificate

      Create Certificate

    10. The next page brings up a dialog explaining the earlier steps in this tutorial, which we already completed. Click Continue.

      Add iOS Certificate

    11. Now upload the certificate you saved to your desktop in Step 4.

      Upload CSR File

    12. Your screen should look like this. Click Generate to move on.

      Generate Certificate

    13. Now click Download to get that newly created certificate.

      Download Certificate

    14. Open the newly downloaded certificate in Keychain Access. It should open in this program automatically if you double click it to open.
    15. Export the certificate (click on My Certificates in the left side bar of Keychain Access). Then right click on the certificate matching the name of your app, and click on Export.

      Keychain Access

    16. Save to desktop as my_cert.p12 (must be in .p12 format).
    17. Now convert the certificate to my_cert.pem in preparation for uploading to PubNub with the following command:
      		openssl pkcs12 -in my_cert.p12 -out my_cert.pem -nodes -clcerts
    18. Verify the cert was created correctly by running one of the following commands (depending on whether you are working with a development or production certificate):
      		# For Development Certs
      		openssl s_client -connect
      			gateway.sandbox.push.apple.com:2195 -cert
      			my_cert.pem -key my_cert.pem
      		# For Production Certs
      		openssl s_client -connect gateway.push.apple.com:2195
      			-cert my_cert.pem -key my_cert.pem
    19. Upload the valid certificate to PubNub via https://admin.pubnub.com. Select your App on the Apps screen.

      Uploading Certificate

    20. Select your keys from the next screen.
    21. In the key options screen, upload my_cert.pem (make sure to select whether it is Development or Production).

      Mobile Push Portal

    Visit Apple APNS docs to learn more about APNS and how it works.

  2. We assume that you have installed phonegap in your environment in the otherwise you can install it following the next steps here.

    According to the name given for your App in Apple developer portal, your App received an id which will use like unique identifier to associate your App to APNs.

    1. Create the phonegap project with push notification template, this has to contain the identifier given for your App in Apple developer portal.
                  phonegap create myApp
                      --id "YOUR IDENTIFIER HERE" 
                      --name "PHONEGAP-PUSH-DEMO" 
                      --template phonegap-template-push
    2. Go to \www\js\index.js inside of this file you will find the callback registration which will be received the device token from APNs. This token must be sent to your backend in order to send notification to your device when your App is offline.

      Callback Registration

    3. Connect your device iPhone or iPad to your Mac.
    4. Add ios to your the project if this is not added.
      • phonegap install ios
      • phonegap build
    5. Go to \platforms\ios folder here you can find the {project}.xcodeproj, open this.
    6. Inside of the XCode select the main file and go to General fill the information hidden:

      Xcode Generals tab

    7. Now go to Build Settings and fill the information hidden:

      Xcode Build Settings tab

    8. Now go to capabilities and activate the push notification feature.

      Xcode Capabilities tab

    9. Select your device and build.

      After compiling and deploy your App in your device you can see in the console log the the device token returned by APNs.

      Xcode console log

  3. After receiving the device token you must share this with your backend in order to send the push notification when this is offline. In this point is where PubNub helps us to resolve many problems and make our life easier.

    PubNub Mobile Push Gateway allows us to associate the device token received from APNs to a channel or a set of channels of the PubNub's Network, therefore when a new message is published to a channel, this message will not only be disperse through the PubNub's Network also if your App is offline or is not running in the front, this message will be sent as push notification through the APNs.

    The first step to do, it is to add the PubNub SDK to your PhoneGap project. Then go to \www\index.html and add the reference from CDN.

    <script src="https://cdn.pubnub.com/sdk/javascript/pubnub.4.13.0.js"></script>

    Add PubNub SDK

    Now go to \www\js\index.js and add the PubNub instance in onDeviceReady callback, associate the device token to a channel subscribed as soon as we receive the token from the APNs.

            var pubnub = null;
    
            var app = {
                initialize: function() {
                    this.bindEvents();
                },
                bindEvents: function() {
                document.addEventListener('deviceready', this.onDeviceReady, false);
                },
                onDeviceReady: function() {
                    pubnub = new PubNub({
                        publishKey: 'YOUR PUBLISH KEY',
                        subscribeKey: 'YOUR SUBSCRIBE KEY'
                    });
    
                    pubnub.subscribe({ channels: ['channel1'] });
    
                    app.setupPush();
                },
                setupPush: function() {
                    var push = PushNotification.init({
                        "android": {
                        "senderID": "XXXXXXXX"
                        },
                        "browser": {},
                        "ios": {
                            "sound": true,
                            "vibration": true,
                            "badge": true
                        },
                        "windows": {}
                    });
    
                push.on('registration', function(data) {
                    console.log('registration event: ' + data.registrationId);
    
                    pubnub.push.addChannels({
                        channels: ['channel1'],
                        device: data.registrationId,
                        pushGateway: 'apns'
                    },
                    function(status) {
                        console.log(status);
                    });
    
                    var oldRegId = localStorage.getItem('registrationId');
    
                    if (oldRegId !== data.registrationId) {
                        localStorage.setItem('registrationId', data.registrationId);
                    }
    
                    var parentElement = document.getElementById('registration');
                    var listeningElement = parentElement.querySelector('.waiting');
                    var receivedElement = parentElement.querySelector('.received');
    
                    listeningElement.setAttribute('style', 'display:none;');
                    receivedElement.setAttribute('style', 'display:block;');
                });
    
                push.on('error', function(e) {
                    alert("push error = " + e.message);
                });
    
                push.on('notification', function(data) {
                    console.log('notification event');
                    navigator.notification.alert(
                    data.message,		// message
                    null,              // callback
                    data.title,       // title
                    'Ok'             // buttonName
                    );
                });
                }
            };

    Build your Phonegap project and deploy this over your device as soon as how the application is running, press the home button.

Now you can use javascript from whatever way: web, node or from other other Phonegap app and publish a message with the same publishKey and subscribeKey which are been used to initialize the instance on your Phonegap project.

var PubNub = require('pubnub');

var pubnub = new PubNub({
	publishKey: 'YOUR PUBLISH KEY HERE',
	subscribeKey: 'YOUR SUBSCRIBE KEY HERE'
});

var payload = {
	pn_apns: {
		aps : {
		alert: 'hi buddy!',
		badge: 1,
		sound: 'melody'
		}
	}
};

pubnub.publish({ message: payload, channel: 'channel1'}, function(err, res) {
	console.log(err);
	console.log(res);
});

Demo Ready

For details on how to retrieve your mobile device push tokens and configuring for mobile gateway receipt on PhoneGap please check https://github.com/phonegap/phonegap-plugin-push/blob/master/docs/API.md#pushonregistration-callback

Also check out for Ionic: https://docs.ionic.io/services/push/#registering-device-tokens

pubnub.push.addChannels() associates a channel to a registration token.
pubnub.push.addChannels(
    {
        channels: ['a', 'b'],
        device: 'niceDevice',
        pushGateway: 'apns' // apns, gcm, mpns
    },
    function(status) {
        if (status.error) {
            console.log("operation failed w/ error:", status);
        } else {
            console.log("operation done!")
        }
    }
);
pubnub.push.removeChannels() disassociates a channel to a registration token.
pubnub.push.removeChannels(
    {
        channels: ['a', 'b'], 
        device: 'niceDevice', 
        pushGateway: 'apns' // apns, gcm, mpns
    },
    function(status) {
        if (status.error) {
            console.log("operation failed w/ error:", status);
        } else {
            console.log("operation done!")
        }
    }
);
For other platform-specific information on provisioning devices and channels, please see our detailed 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>
ParameterTypeRequiredDescription
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 subscribeKey.
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/FCM, 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.
To make it properly formatted for receipt via APNS, we must add a pn_apns attribute to it, like so:
{
	"name" : "Fitchwitz Technology",
	"pn_apns" : {
		"aps" : {
			"alert" : "Fitchwitz Technology",
            "badge": 2,
            "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_apns must contain a dictionary of valid keys and values. pn_apns must begin with a sole aps child key, and cannot be a string, int, or array. For more info on proper formatting of your pn_apns payload, see Apple's reference.
To make it properly formatted for receipt via MPNS, we must add a pn_mpns attribute to it, like so:
{
    "pn_mpns": {
        "type" : "toast",
        "text1" : "Stock Trade Activity",
        "text2" : "100 XYZ Stock @ $ 60 BUY is being ordered. Your order is in process. If you did not order, please call helpdesk."
    },
    "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_mpns must contain a dictionary of valid keys and values. pn_mpns must have type key to indicate type of push message. The types of push messages are toast, flip, cycle, iconic.  For more info on proper formatting of your pn_mpns payload, see Microsoft's reference.
 
In the delay parameter, PubNub expects the time (in seconds) when the message should be delivered. Possible values are 0, 450, or 900. 0 is immediate and the others are in seconds. Defaults to 0.
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/FCM, 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/FCM, APNS, and MPNS devices with the PubNub PhoneGap V4 client:
var pubnub = new PubNub({
    /* initiation arguments */
})
var pushPayload = {
    "pn_apns": {
        "aps" : { 
            "alert": "hi",
            "badge": 2,
            "sound": "melody"
        },
        "c" : "3"
    },
    "pn_gcm": {
        "data" : {
            "a" : "1"
        }
    },
    "b" : "2"
}

pubnub.publish(
    { 
        message: pushPayload
    },
    function (status) {
        // handle publish status.
    }
);
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 PNMessage.apns/gcm attributes, 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/FCM 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_gamekeys.
    {
        "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.

Yes, you can set an expiration time when publishing a push notification via APNS. Timeouts are measured in seconds (default is 3600, or 1 hour) and are set via the top level key of pn_ttl. For example, to set the timeout to 60 seconds (1 minute):

    {
        "pn_apns" : {
            "aps" : {
                "alert" : "You got mail."
            }
        },
        "pn_ttl" : 60
    }

Note that Apple will only queue a single message per device/app. For example, if you send 10 push notifications to a device that's powered off, then all notifications besides the last one are discarded, regardless of TTL.

Sometimes it is desirable to exclude a device from a group push notification. For example if a user has multiple devices registered to same channel and wants to send a group push notification he/she may want to not receive the same push on own devices. We support the pn_exceptions parameter in the payload to handle this. The pn_exceptions parameter accepts "device push tokens" (the same token used to register the device for push messages).

    {
        "pn_apns" : {
            "aps" : {
                "alert" : {
                    "body" : "hello"
                }
            },
            "pn_exceptions" : [
                "da284603e1e96ac453541cd1942659808a69c09fb1dbb2e3c11aba6cdcaec642"
            ]
        }
    }
    {
        "pn_apns" : {
            "aps" : {
                "alert" : {
                    "body" : "hello"
                }
            },
            "pn_exceptions" : [
                "5821e49019f3554872c3897dd800367bf803aa28871699b0e5960fba203446e9",
                "da284603e1e96ac453541cd1942659808a69c09fb1dbb2e3c11aba6cdcaec642"
            ]
        }
    }
    {
        "pn_gcm" : {
            "alert" : "hello",
            "pn_exceptions" : [
                "2643d955c7f2506e55f225b56da7eb8676cced80de93df51aad7569ee833b92f"
            ]
        }
    }
Inform customers of unregistered/inactive push devices via a webhook (similar to presence webhooks).
The following events will trigger the webhook. All errors should trigger immediately after a push (except for feedback which can happen after 5 minutes of a push).
  • Feedback -­ Apple feedback service ­- PubNub push server polls the feedback server after 5 minutes of a push to get list of inactive/uninstalled devices.
  • Remove - Invalid token error -­ Usually indicates when a sandbox token is used in production or vice versa.
  • Update -­ Canonical ID -­ The device has multiple tokens (old and new), replace the old token with new token.
  • Remove - NotRegistered - App was uninstalled or no longer configured for push notifications.
	HTTP POST
	Content­Type: application/json
	{
		"sub_key" : <sub­key>,
		"action" : <action contains extra details about how the device was removed ­ see events section>
		"device" : <device token>,
		"platform" : "apns|gcm|mpns",
		"timestamp" : <unix timestamp (utc) when the device was removed>
	}
An APNS device was uninstalled from feedback.
	{
		"sub_key" : "sub­c­e0d8405a­b823­11e2­89ba­02ee2ddab7fe",
		"action" : "feedback",
		"device" :"904181a3fc8bfaf95cc40551d81b5b8d0bd1d42c38b1e496648132a555325e8c",
		"platform" : "apns",
		"timestamp" : 1444241230
	}
A GCM/FCM device was updated from old token APA91bEgK4D to new token ta28zYhV.
	{
		"sub_key" : "sub­c­4745b1e4­19ba­11e4­bbbf­02ee2ddab7fe",
		"action" : "update",
		"old_device": "APA91bEgK4D"
		"device" : "ta28zYhV"
		"platform" : "gcm",
		"timestamp" : 1441230130
	}
A MPNS device was uninstalled.
	{
		"sub_key" : "sub­c­8a888f2c­d7a1­11e3­8c07­02ee2ddab7fe",
		"action" : "remove",
		"device" : "http://sn1.notify.live.net/throttledthirdparty/01.00/AQG2MdvoLlZFT7­VJ2TJ5LnbAgAAAAADAQAAAAQUZm52OkRFNzg2NTMxMzlFMEZFNkMFBlVTU0MwMQ"
		"platform" : "mpns",
		"timestamp" : 1400218910
	}
 
If a device has been registered to receive Mobile Push Gateway messages via GCM/FCM, 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/FCM, completely circumventing PubNub infrastructure. It requires a registration ID. Taken from Google's GCM/FCM 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 have implemented mobile push notifications into your PubNub application but now you are having some troubles. Maybe it's missing messages on client devices, getting duplicate messages, getting messages meant for another user/device. Whatever it is, we will provide the best tools and techniques for finding the root cause and resolving, or at least just getting all the necessary data points to send to PubNub Support to assist with troubleshooting.

You can do some high level debugging using the channel's -pndebug channel and checking to see if the device is still registered to the channel. Messages from -pndebug come from the APNS and GCM/FCM services (from Apple and Google, not PubNub). Here are the steps:

  1. Use the PubNub Debug Console to subscribe to the channel's -pndebug channel. If the channel you are publishing to is foo, then subscribe to foo-pndebug. Make sure you use the right pub/sub keys.
  2. Add 'pn_debug':true to your message payload at the top level.
        {
            "pn_gcm": {
                "data": {
                    "message": "hello"
                }
            },
            "pn_apns": {
                "aps": {
                    "alert": "hello"
                }
            },
            "pn_debug": true
        }
  3. Publish the message to channel foo, not to the channel's -pndebug channel. You can publish from your client or server application or from another instance of Debug Console (again, make sure you use the same pub/sub keys). You should see useful error messages in the Debug Console where you are subscribing to foo-pndebug, if there are any problems with the push message registration.

The following message shows how many devices successfully received the push notification that were registered for push messages on the target channel for each push service.

Devices found for push notification apns: 2 gcm: 3 mpns: 0

The following messages are examples of the types of messages that GCM/FCM and APNS push services can send back to PubNub's mobile push notification gateway servers.

    gcm Error: InvalidRegistration Devices: null
    gcm WARNING error: NotRegistered, sub_key: sub-c-..., channel: my_channel, reg_id: APA91bHRRxfHHB_T0AVojoJx..., timetoken: 14567269547473296
    apns INFO Certificate for sub-c-... valid (expiration: Sep 14 08:58:26 2016 GMT)
    apns ERROR Error on APNS send for subkey sub-c-... / channel gone_fishing / device 2a0a6234ffdb85df6624cf0546...: invalid token

All of the above messages can be sent to your server using PubNub's Mobile Push Gateway web hooks. A web hook is a URL (that you can have us configure on your keys) to a REST endpoint on your server. As messages come back to PubNub from the mobile push notification services, PubNub will relay them onto your REST endpoint for you to log and process as you require. Contact PubNub Support to request this configuration for your keys.

You can also check to see if the device is still registered to the channel after you publish the push notification using a simple REST URL in the browser.

  1. http://pubsub.pubnub.com/v1/push/sub-key/your_sub_key/devices/device_reg_token?type=push_type
  • where push_type is either gcm or apns
  • and device_reg_token is the device's registration token

This will return all channels the device is still registered for push notification for the push type provided.

Example of response:

["demo","demo1","demo2"]

If that list comes back empty then there was likely a device registration token issue (invalid token or device not registered, for example). This might happen because the device token was reported as invalid by the push notification services (APNS or GCM/FCM) and PubNub in turn unregisters that device token from all channels. But the -pndebug channel should reveal the reason for this to you.

Most times it is not PubNub that is causing the push notification issues. Often it is an invalid registration token (APNS or GCM/FCM) or a device with two valid registration tokens (yes, it can actually happen) or the push service cert or key is no longer valid. Testing push notifications without PubNub getting involved is the best way to eliminate, or hone in on, the area of probable fault.

There are a few good online tools for testing GCM/FCM push notifications and one native Mac app.

For APNS, you can run a simple Python script that uses your push certificate (.pem file) to verify that the certificate is valid. And optionally, you can specify a device registration token to which test push notifications will be sent. See our knowledge base article, How Do I Test My PEM Key, for full details.

For more rich UI/UX tools, you can find APNS test apps for the Mac (in the App Store) as well as online web apps:

See also:

  1. Apple Doc Troubleshooting Push Notifications

For additional platform and endpoint information, please see our detailed Android, Objective-C, Swift, and .NET Mobile Gateway guides.