Implement Push Notifications for android and iOS (phonegap) – part 3

This tutorial is the third part of a three-part series on how to do push notifications integration with your app for android and iOS.

Install the PushPlugin phonegap plugin from its github location via the Cordova CLI:

cordova plugin add https://github.com/phonegap-build/PushPlugin
PushPlugin Phonegap Plugin

PushPlugin Phonegap Plugin

Add iOS and android platform using cordova CLI.

cordova platform add ios
cordova platform add android
cordova platform add

cordova platform add

Locate the PushNotification.js file that was installed into your project-root/plugins folder. This file must be copied into your project-root/www/js folder and referenced from the index.html currently.

https://github.com/phonegap-build/PushPlugin/blob/master/www/PushNotification.js

copy from phonegap plugin folder

copy from phonegap plugin folder

copy to www folder

copy to www folder

Write custom script for push notification plugin. Grab project id from Google Developer Console and put it inside this script. After that save as PushCustom.js in www/js.

// JavaScript Document
var pushNotification;

function onDeviceReady() {
		document.addEventListener("backbutton", function(e) {}, false);
		try {
			pushNotification = window.plugins.pushNotification;
			if (device.platform == 'android' || device.platform == 'Android' || device.platform ==
				'amazon-fireos') {
				pushNotification.register(successHandler, errorHandler, {
					"senderID": "xxxxxxxxxxxxx",
					"ecb": "onNotification"
				}); // required!
			} else {
				pushNotification.register(tokenHandler, errorHandler, {
					"badge": "true",
					"sound": "true",
					"alert": "true",
					"ecb": "onNotificationAPN"
				}); // required!
			}
		} catch (err) {
			txt = "There was an error on this page.\n\n";
			txt += "Error description: " + err.message + "\n\n";
			alert(txt);
		}
	}
	// handle APNS notifications for iOS

function onNotificationAPN(e) {
		if (e.alert) {
			// showing an alert also requires the org.apache.cordova.dialogs plugin
			navigator.notification.alert(e.alert);
		}
		if (e.sound) {
			// playing a sound also requires the org.apache.cordova.media plugin
			var snd = new Media(e.sound);
			snd.play();
		}
		if (e.badge) {
			pushNotification.setApplicationIconBadgeNumber(successHandler, e.badge);
		}
	}
	// handle GCM notifications for Android

function onNotification(e) {
	switch (e.event) {
		case 'registered':
			if (e.regid.length > 0) {
				// Your GCM push server needs to know the regID before it can push to this device
				// here is where you might want to send it the regID for later use.
				alert("regID = " + e.regid);
			}
			break;
		case 'message':
			// if this flag is set, this notification happened while we were in the foreground.
			// you might want to play a sound to get the user's attention, throw up a dialog, etc.
			if (e.foreground) {
				// on Android soundname is outside the payload.
				// On Amazon FireOS all custom attributes are contained within payload
				var soundfile = e.soundname || e.payload.sound;
				// if the notification contains a soundname, play it.
				// playing a sound also requires the org.apache.cordova.media plugin
				var my_media = new Media("/android_asset/www/" + soundfile);
				my_media.play();
			}
			break;
		case 'error':
			break;
		default:
			break;
	}
}

function tokenHandler(result) {
	alert('device token = ' + result);
	// Your iOS push server needs to know the token before it can push to this device
	// here is where you might want to send it the token for later use.
}

function successHandler(result) {}

function errorHandler(error) {}
document.addEventListener('deviceready', onDeviceReady, true);

Add the following script line to your index.html to reference the PushNotification.js and PushCustom.js.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
    <title></title>

    <link href="lib/ionic/css/ionic.css" rel="stylesheet">
    <link href="css/style.css" rel="stylesheet">

    <!-- IF using Sass (run gulp sass first), then uncomment below and remove the CSS includes above
    <link href="css/ionic.app.css" rel="stylesheet">
    -->

    <!-- ionic/angularjs js -->
    <script src="lib/ionic/js/ionic.bundle.js"></script>

    <!-- cordova script (this will be a 404 during development) -->
    <script src="cordova.js"></script>
    <script type="text/javascript" src="js/PushNotification.js"></script>

    <!-- your app's js -->
    <script src="js/app.js"></script>
  </head>
  <body ng-app="starter">

    <ion-pane>
      <ion-header-bar class="bar-stable">
        <h1 class="title">Ionic Blank Starter</h1>
      </ion-header-bar>
      <ion-content>
      </ion-content>
    </ion-pane>
  </body>
</html>

Build and run the application via eclipse (ADT installed) and Xcode6.

cordova build ios
cordova build android

Open your editor and create a file called simplepush.js.

Android setting

Go to your GCM console and locate the Server API key (click the API Access link in the menu on the left to locate they keys). http://blog.revivalx.com/2014/08/29/implement-push-notifications-for-android-and-ios-phonegap-part-1/

Get the registration id returned to our application from the console. I like to use the Android adb tool so I can run logcat to watch the console while my application is running. Assuming you have the android-sdk tools and platform-tools set on your environment path you can simply run adb logcat from the command line to show your device log.

Replacing the Sender key and device registration id with yours in simplepush.php.

IOS setting

Go to your apple developer account and locate iOS / APNs development certificates and provisioning profile then install it into your machine.

Get the token id returned to our Xcode console. Open your editor and replacing the token id and passphrase.

<?php
//enable it
//$deviceType = 'ios';
//$deviceType = 'android';

//operation begin
if($deviceType == 'ios'){

$deviceToken = 'xxxxx';
// Put your device token here (without spaces):

// Put your private key's passphrase here:
$passphrase = 'xxxxx';

// Put your alert message here:
$message = 'Technovault is awesome!!!';

////////////////////////////////////////////////////////////////////////////////

$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);

// Open a connection to the APNS server
$fp = stream_socket_client(
	'ssl://gateway.sandbox.push.apple.com:2195', $err,
	$errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);

if (!$fp)
	exit("Failed to connect: $err $errstr" . PHP_EOL);

echo 'Connected to APNS' . PHP_EOL;

// Create the payload body
$body['aps'] = array(
	'alert' => $message,
	'sound' => 'default',
	'badge' => 1
	);

// Encode the payload as JSON
$payload = json_encode($body);

// Build the binary notification
$msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;

// Send it to the server
$result = fwrite($fp, $msg, strlen($msg));

if (!$result)
	echo 'Message not delivered' . PHP_EOL;
else
	echo 'Message successfully delivered' . PHP_EOL;

// Close the connection to the server
fclose($fp);
}
else if($deviceType == 'android'){

$deviceToken = 'xxxxx';

$registrationIds = array($deviceToken);

// prep the bundle
$msg = array
(
    'message' 		=> 'Technovault is awesome!!!',
	'title'			=> '[Warning]',
	'subtitle'		=> 'This is a subtitle. subtitle',
	'tickerText'	=> 'Ticker text here...Ticker text here...Ticker text here',
	'vibrate'	=> 1,
	'sound'		=> 1
);

$fields = array
(
	'registration_ids' 	=> $registrationIds,
	'data'				=> $msg
);

$headers = array
(
	'Authorization: key=' . 'xxxxx',
	'Content-Type: application/json'
);

$ch = curl_init();
curl_setopt( $ch,CURLOPT_URL, 'https://android.googleapis.com/gcm/send' );
curl_setopt( $ch,CURLOPT_POST, true );
curl_setopt( $ch,CURLOPT_HTTPHEADER, $headers );
curl_setopt( $ch,CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch,CURLOPT_SSL_VERIFYPEER, false );
curl_setopt( $ch,CURLOPT_POSTFIELDS, json_encode( $fields ) );
$result = curl_exec($ch );
curl_close( $ch );

echo $result;
}
else {
	echo "Error";
}

Now type the following from the command line where the script was created to run the code and send a push notification:
php simplepush.php

You should hear the notification and see it in your status bar like this on your Android and iOS devices.

19 thoughts on “Implement Push Notifications for android and iOS (phonegap) – part 3

  1. Great tutorial.
    Did you ever had problem with sending notifications to different IOS devices with? I have everything working, devices are properly registered (i have token) but some of them get notifications and some don’t.

  2. I cant find the registration id where is it supposed to be I typed adb logcat while the emulator starts up and I dont see anything about a registration id. Any help would be appreciated new to mobile app dev.

      1. Thanks for the reply I get this warning in the log if it helps

        I/App ( 1908): WARNING: Back Button Default Behavior will be overridden. The backbutton event will be fired!
        V/PushPlugin( 1908): execute: action=register
        V/PushPlugin( 1908): execute: data=[{"senderID":"apt-sentinel-811","ecb":"onNotification"}]
        V/PushPlugin( 1908): execute: jo={"senderID":"apt-sentinel-811","ecb":"onNotification"}
        V/PushPlugin( 1908): execute: ECB=onNotification senderID=apt-sentinel-811
        D/GCMRegistrar( 1908): resetting backoff for com.ionicframework.exampleproject951882
        V/GCMRegistrar( 1908): Registering app com.ionicframework.exampleproject951882 of senders apt-sentinel-811
        W/PluginManager( 1908): THREAD WARNING: exec() call to PushPlugin.register blocked the main thread for 20ms. Plugin should use CordovaInterface.getThreadPool().
        W/ActivityManager( 1262): Unable to start service Intent { act=com.google.android.c2dm.intent.REGISTER pkg=com.google.android.gsf (has extras) } U=0: not found
        D/CordovaLog( 1908): file:///android_asset/www/js/PushCustom.js: Line 83 : OK
        I/chromium( 1908): [INFO:CONSOLE(83)] "OK", source: file:///android_asset/www/js/PushCustom.js (83)
        D/CordovaActivity( 1908): onMessage(spinner,stop)

  3. Thanks for this tutorial ! it’s work great with Android App.

    But i have a problem, when i send more than 1 notification, my device show only the latest but not all.

    Thanks for your answer :/

      1. yes ! i have succefully resolved my problem.

        With the PHP script, the notification replace older (on android, i’ve note tested on ioS),

        You must add in your PHP code “notId”.

        This code specialy :
        // prep the bundle
        $msg = array
        (
        ‘message’ => ‘Technovault is awesome!!!’,
        ‘title’ => ‘[Warning]’,
        ‘subtitle’ => ‘This is a subtitle. subtitle’,
        ‘tickerText’ => ‘Ticker text here…Ticker text here…Ticker text here’,
        ‘vibrate’ => 1,
        ‘sound’ => 1
        );

        for :

        // prep the bundle
        $msg = array
        (
        ‘notId’ => time();
        ‘message’ => ‘Technovault is awesome!!!’,
        ‘title’ => ‘[Warning]’,
        ‘subtitle’ => ‘This is a subtitle. subtitle’,
        ‘tickerText’ => ‘Ticker text here…Ticker text here…Ticker text here’,
        ‘vibrate’ => 1,
        ‘sound’ => 1
        );

        (sorry for my bad english)

      2. yes ! i have succefully resolved my problem.

        With the PHP script, the notification replace older (on android, i’ve note tested on ioS),

        You must add in your PHP code “notId”.

        This code specialy :
        // prep the bundle
        $msg = array
        (
        ‘message’ => ‘Technovault is awesome!!!’,
        ‘title’ => ‘[Warning]’,
        ‘subtitle’ => ‘This is a subtitle. subtitle’,
        ‘tickerText’ => ‘Ticker text here…Ticker text here…Ticker text here’,
        ‘vibrate’ => 1,
        ‘sound’ => 1
        );

        for :

        // prep the bundle
        $msg = array
        (
        ‘notId’ => time(),
        ‘message’ => ‘Technovault is awesome!!!’,
        ‘title’ => ‘[Warning]’,
        ‘subtitle’ => ‘This is a subtitle. subtitle’,
        ‘tickerText’ => ‘Ticker text here…Ticker text here…Ticker text here’,
        ‘vibrate’ => 1,
        ‘sound’ => 1
        );

        (sorry for my bad english)

  4. Hi,
    I want to send my regID from Pushcustom.js to my php page on server.Please anyone help. I try $http command but it dosnt work.

      1. I didn’t got any error message. Actually i got an alert of token on my mobile but i want to use your code into my controller in app.js file or directly send the the token from Pushcustom.js file to my server.

  5. this is how i try to send data to server
    if (e.regid.length > 0) {

    // Your GCM push server needs to know the regID before it can push to this device
    // here is where you might want to send it the regID for later use.
    alert(“regID = ” + e.regid);
    console.log(e.regid);
    var tokenID = e.regid;
    //$.post()
    $.post(‘http://papers.com.pk/ionic.php’,{token: tokenID},function(response){
    alert(“Success”);

    });

    }

Leave a Reply

Your email address will not be published. Required fields are marked *