Push Notifications in Ionic 2

Updated to Ionic 3

Push Notifications allow app developers to notify users at any time, users don’t have to be in the app or using their devices to receive them. With the help of some good tutorials, push notifications can be implemented very easy in Ionic 2 which supports both iOS and Android.

Android uses FCM(Firebase Cloud Messaging (FCM) earlier known as GCM) and iOS uses APNS for push notification.

Full Client and Server code is available on Github
Push Notification flow

Setting up Ionic 2 App to generate device token

For Android, follow FCM setup instructions. It will give you SERVER_KEY and SENDER_ID. SERVER_KEY is used by server to send push notification and SENDER_ID is used by device to generate device token. For iOS, nothing required to generate device token.

Replace YOUR_SENDER_ID in config.xml with above SENDER_ID

<plugin name="phonegap-plugin-push" spec="1.8.2">    
<variable name="SENDER_ID" value="YOUR_SENDER_ID"/>
</plugin>

Add device token generation code in your main app constructor like below and replace YOUR_SENDER_ID in Push.init() method with above SENDER_ID

import {Component, ViewChild} from "@angular/core";
import {AlertController, Nav, Platform} from "ionic-angular";
import {StatusBar} from "@ionic-native/status-bar";
import {SplashScreen} from "@ionic-native/splash-screen";
import {Push, PushObject, PushOptions} from "@ionic-native/push";
import {TabsPage} from "../pages/tabs/tabs";
import {DetailsPage} from "../pages/details/details";

@Component({
template: '<ion-nav [root]="rootPage"></ion-nav>'
})
export class Ionic2PushApp {
@ViewChild(Nav) nav: Nav;
rootPage: any;

constructor(public platform: Platform,
public statusBar: StatusBar,
public splashScreen: SplashScreen,
public push: Push,
public alertCtrl: AlertController) {
this.rootPage = TabsPage;
platform.ready().then(() => {
this.statusBar.styleDefault();
this.splashScreen.hide();
this.initPushNotification();
});
}

initPushNotification() {
if (!this.platform.is('cordova')) {
console.warn("Push notifications not initialized. Cordova is not available - Run in physical device");
return;
}
const options: PushOptions = {
android: {
senderID: "YOUR_SENDER_ID"
},
ios: {
alert: "true",
badge: false,
sound: "true"
},
windows: {}
};
const pushObject: PushObject = this.push.init(options);

pushObject.on('registration').subscribe((data: any) => {
console.log("device token ->", data.registrationId);
//TODO - send device token to server
});

pushObject.on('notification').subscribe((data: any) => {
console.log('message', data.message);
//if user using app and push notification comes
if (data.additionalData.foreground) {
// if application open, show popup
let confirmAlert = this.alertCtrl.create({
title: 'New Notification',
message: data.message,
buttons: [{
text: 'Ignore',
role: 'cancel'
}, {
text: 'View',
handler: () => {
//TODO: Your logic here
this.nav.push(DetailsPage, {message: data.message});
}
}]
});
confirmAlert.present();
} else {
//if user NOT using app and push notification comes
//TODO: Your logic on click of push notification directly
this.nav.push(DetailsPage, {message: data.message});
console.log("Push notification clicked");
}
});

pushObject.on('error').subscribe(error => console.error('Error with Push plugin', error));
}
}

Run on physical android and iOS devices to see device token in console. Use Xcode to run on iOS device. Note down device token to send push notification. Device token doesn’t generate in browser or simulator and might give exceptions which you can ignore.

ionic platform add android
ionic build android --prod
ionic platform add ios
ionic build ios --prod
ionic run android // To run on real android device
//Use Xcode to run on real iOS device
Click here for Client code and here for Server code available on Github

Server Setup for Push Notifications

For Android, run below java code to send push notification. Replace DEVICE_TOKEN by device token obtained from device and SERVER_KEY by Server key obtained from FCM.

import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

public class AndroidPush {

/**
* Replace SERVER_KEY with your SERVER_KEY generated from FCM
* Replace DEVICE_TOKEN with your DEVICE_TOKEN
*/
private static String SERVER_KEY = "YOUR_SERVER_KEY";
private static String DEVICE_TOKEN = "YOUR_DEVICE_TOKEN";


/**
* USE THIS METHOD to send push notification
*/
public static void main(String[] args) throws Exception {
String title = "My First Notification";
String message = "Hello, I'm push notification";
sendPushNotification(title, message);
}


/**
* Sends notification to mobile, YOU DON'T NEED TO UNDERSTAND THIS METHOD
*/
private static void sendPushNotification(String title, String message) throws Exception {
String pushMessage = "{\"data\":{\"title\":\"" +
title +
"\",\"message\":\"" +
message +
"\"},\"to\":\"" +
DEVICE_TOKEN +
"\"}";
// Create connection to send FCM Message request.
URL url = new URL("https://fcm.googleapis.com/fcm/send");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("Authorization", "key=" + SERVER_KEY);
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestMethod("POST");
conn.setDoOutput(true);

// Send FCM message content.
OutputStream outputStream = conn.getOutputStream();
outputStream.write(pushMessage.getBytes());

System.out.println(conn.getResponseCode());
System.out.println(conn.getResponseMessage());
}
}

That’s it, push notifications working on Android device.

For iOS, there are few additional steps to generate some certificates. You must have paid developer account to generate certificate. Follow APNS setup instructions to generate .p12 certificate.

Use following code to push notification to iOS device. It uses https://github.com/notnoop/java-apns.

import com.notnoop.apns.APNS;
import com.notnoop.apns.ApnsService;

public class IOSPush {
/**
* Replace DEVICE_TOKEN with your DEVICE_TOKEN
* Replace PATH_TO_P12_CERT with your YOUR_P12_CERTIFICATE_PATH
* Replace CERT_PASSWORD with your YOUR_P12_CERTIFICATE_PASSWORD
*/
private static String DEVICE_TOKEN = "YOUR_DEVICE_TOKEN";
private static String PATH_TO_P12_CERT = "YOUR_P12_CERTIFICATE_PATH";
private static String CERT_PASSWORD = "YOUR_P12_CERTIFICATE_PASSWORD";

public static void main(String[] args) {
ApnsService service =
APNS.newService()
.withCert(PATH_TO_P12_CERT, CERT_PASSWORD)
.withSandboxDestination()
.build();

String payload = APNS.newPayload()
.alertBody("My first notification\nHello, I'm push notification")
.sound("default")
.build();

service.push(DEVICE_TOKEN, payload);
System.out.println("The message has been hopefully sent...");
}
}

That’s it, push notifications working on iOS device.

Phew! That was a lot to get through, but it was all worth it

See references for push notification server and client code on github.
Please hit the ♥ below if you found this post useful, so that others can read it.

Some good references