Setting Up Amazon SNS & Apache Cordova for Push Notifications

This guide walks you though creating a Cordova app for Push Notifications on iOS and Android. We will use the Apache Cordova platform and the Amazon SNS service to build and test our Push Notifications.

There is a lot to learn about Push Notifications, but the intention here is to get you up and running with a proof of concept.

You will need:

  • MacOS High Sierra — 10.13.1
  • Homebrew — 1.4.0
  • Node.js — v9.2.1
  • NPM — 5.5.1
  • Xcode — 9.2 (9C40b)
  • Git — 2.13.1
  • Cordova — 7.0.1
  • Gradle — 4.4

Useful Terminology

  • APNS — Apple Push Notification Service
  • GCM — Google Cloud Messaging
  • FCM — Firebase Cloud Messaging (GCM is now replaced/included in FCM)
  • SNS — Amazon Simple Notification Service (Not to be confused with SMS)

Amazon Guides

Amazon provides the following guides setup guides for APNS and GCM. I found some of the information in these to be out of date, or too hairy for a JavaScript developer who can not bring himself to install Eclipse.

You will learn how to:

  • Create a sample Cordova app with the phonegap-push-plugin
  • Obtain a device regustrationId (also known as a Device Token) from the Sample App that can used to send you Push Notifications across the network.
  • Create APNS and GCM certificates for your app
  • Push APNS and GCM notifications to your app via the Amazon SNS console.

The steps you are about to read, are split into three sections:

  1. Base Steps — which apply to the whole project
  2. iOS Steps
  3. Android Steps

Base Steps

In your terminal:

cordova create cordova-remote-push-notifications org.apache.cordova.RemotePushNotificationsApp RemotePushNotificationsApp
cd cordova-remote-push-notifications
# android@latest not currently compatiable with code-push@latest 2017–12–12
cordova platform add android@6.3.0
cordova platform add ios@latest
# Install CocoaPods Xcode Package Manager
# (If not already installed)
sudo gem install cocoapods
# Setup the Cocoapod master repo
pod setup
# Install the Cocoapod depencies in the iOS platform directory
cd platforms/ios/
pod install
# Install Phonegap-Plugin-Push
cordova plugin add phonegap-plugin-push

Add the following code to www/js/index.js the onDeviceReady() callback:

onDeviceReady: function() {
this.receivedEvent('deviceready');

var push = PushNotification.init({
android: {},
browser: {
pushServiceURL: 'http://push.api.phonegap.com/v1/push'
},
ios: {
alert: "true",
badge: "true",
sound: "true"
},
windows: {}
});
push.on('registration', function (data) {
console.dir(data)
alert('Event=registration, registrationId=' + data.registrationId)
});
push.on('notification', function (data) {
console.log(data)
alert('Event=notification, message=' + data.message)
});
push.on('error', function (err) {
console.log(err)
alert('Event=error, message=' + err.message)
});
},

iOS APNS Guide

In your terminal:

# Open the workspace in Xcode
open -a Xcode platforms/ios/RemotePushNotificationsApp.xcworkspace
# Select the correct 1) Certificate and 2) Device you wish to build to

While you are in Xcode, Toggle on “Push Notifications”:

While you are in Xcode, Toggle on “Push Notifications”
# Build and run the App
cordova build ios
cordova run ios
While the app is running on your iOS device, get the registrationId logged in the Safari Developer Console. Save this registrationId somewhere, you will need to send messages to the device via the Amazon SNS console.

Create APNS Certificates and Keys

Open the Apple Developer console in your web browser and select Certificates, IDs & Profiles.

Click the Add button to add a new certificate.

For testing purposes, select the Development certificate “Apple Push Notification service SSL (Sandbox)” and click the Continue button.

Select the app id from the drop-down list. (This app id is generated by Xcode when you sign the build with the your developer account credentials.)

Click the Continue button on the next screen.

Obtain an APNS SSL Certificate

Open Keychain Access on your MacBook and select: “Keychain Access > Certificate Assistant > Request a Certificate from a Certificate Authority”:

After clicking the “Continue” button, fill out the Certificate form, press Continue.

When the cert is ready, save it to your Desktop and click the Done button on the next screen.

Choose the cert file from your desktop in the Apple Developer Portal.

Your cert file should contain the Base 64 certificate request key.

Click the Continue button to upload your cert to Apple.

In less than a minute the Apple Developer Portal should show you a download link for your Apple Push Cerificate. Click the Download button and save your Desktop.

If you click the Done button you will see that your Push cert is now listed.

Click the Download button to save your push certificate to the Desktop. It should download a .cer file.

In your shell, convert the .cer file to a .pem. (Amazon SNS uses .pem)

openssl x509 -in ~/Desktop/aps_development.cer -inform DER -out ~/Desktop/PushCert.pem

Obtain the App Private Key

Import the Apple Push Notifications certificate (aps_development.cer) that your downloaded from the Apple Developer Portal earlier, into the Keychain Access app.

You should see the certificate listed with the name of your app.

Expand your certificate and select the private key. Right click and export your Private Push Key to a .p12 file.

Save the key file to the Desktop, naming it “PushKey”.

You sill be asked to provide an encryption password for your private key file.

You will likely be asked to enter your system or login password in order to export your private key from the Keychain Access app to the file-system.

Convert the PushKey.p12 file to a PushKey.pem file using opensslin your shell.

openssl pkcs12 -in ~/Desktop/PushKey.p12 -out ~/Desktop/PushKey.pem -nodes -clcerts
# Enter Import Password: ************
# MAC verified OK

Verify the Certificate and App Private Key

openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert ~/Desktop/PushCert.pem -key ~/Desktop/PushKey.pem
# If you see something like the following block, then everything is working as expected.
# SSL handshake has read 3662 bytes and written 2403 bytes
# — -
# New, TLSv1/SSLv3, Cipher is DES-CBC3-SHA
# Server public key is 2048 bit
# Secure Renegotiation IS supported
# Compression: NONE
# Expansion: NONE
# No ALPN negotiated
# SSL-Session:
# Protocol : TLSv1.2
# Cipher : DES-CBC3-SHA
# Session-ID:
# Session-ID-ctx:
# Master-Key: E6ABA44F7F02DC…
# Start Time: 1516227913
# Timeout : 300 (sec)
# Verify return code: 0 (ok)
# — -

Setup and Test your Amazon SNS iOS App

Navigate to the Applications section in your Amazon SNS console:

Click the “Create platform application” button and fill in the following form.

Click the “Load credentials from file” button. You should see the certificate and key loaded.

Click the “Create platform application” button and you should see the application added to the list.

Click on the application in the list and the click the “Create application endpoint” button.

Add the Device Token (registrationId) that you saved from the Safari Developer console earlier and click the “Add endpoint” button.

Click on the ARN link.

Check the item with the Device Token (registrationId) that you added, and click the “Publish to endpoint” button.

Create a Raw text message and click the “Publish message” button.

Within thirty seconds you should see the notification arrive on your iOS device.

If you swipe or click the notification, it should take you into the app, where your Push Notification event is replayed.

Congrats! You can now send Push Notifications through Amazon SNS to iOS devices subscribed to your APNS certificate.

Android GCM/FCM Guide

You have already added the android platform at the start of the steps above, so no need to add that again here.

Create a Google API Project and Credentials

Visit the Google Developer Console Credentials Page.

Note: You may need to click the blue “Enable APIs and Services” if it appears.

Click on the “Create” button.

Name your application and click on the “Create” button.

You will now see the application name at the top of the window (highlighted in this image with the red oval). Click the “Create credentials” button and select “API” from the dropdown menu.

Your Google API Credentials have been created.

Add a GCM Mobile Project

Navigate to the Add Mobile interface, and begin setting up Google Cloud Messaging for your mobile application

Note: If the user Force-Stops the app, Ie: , Settings > Apps > YourApp > Force Stop then when the user starts the app again, a new registration number will be provided. Source: Stack Overflow

Click on “Pick a Platform”. Click on “Android App”

Name your mobile app appropriately, then click “Choose and configure services”.

Note: You will need to pick a valid package name for you app. The package name is the same as the Widget Id from your config.xml file. For example if your config.xml file looks like this…

<?xml version=’1.0' encoding=’utf-8'?>
<widget id=”org.apache.cordova.RemotePushNotificationsApp” version=”1.0.0" xmlns=”http://www.w3.org/ns/widgets" xmlns:cdv=”http://cordova.apache.org/ns/1.0">

…in this case, use “org.apache.cordova.RemotePushNotificationsApp” as your package name.

Click on “Generate Configuration Files”.

You should now see a link to download your google-services.json file as well as your Server API Key and Sender ID. You will need all of these to send notifications to your app.

First, click on the on the “Download google-services.json” button. Save this file to your ~Downloads folder.

Copy google-services.json into your platforms/android directory, so that it can be picked up by the Cordova Android build process.

cp ~/Downloads/google-services.json platforms/android/google-services.json

You will need to add your Sender Id to the www/js/index.js file so that Google can connect your app to the notifications endpoint.

onDeviceReady: function() {
this.receivedEvent('deviceready');
    var push = PushNotification.init({
android: {
// Add your Google Mobile App SenderId here
senderID: 24XXXXXXXXX0
},
browser: {
pushServiceURL: 'http://push.api.phonegap.com/v1/push'
},
ios: {
alert: "true",
badge: "true",
sound: "true"
},
windows: {}
});
    ...
}

Update Android Studio Dependencies

Open Android Studio and make sure you have Android Support Repository installed. Don’t forget to check for Android Studio Updates and installed them!

![img/cordova-remote-push-notifications-android-sdk-support-repo.jpg](img/cordova-remote-push-notifications-android-sdk-support-repo.jpg)

cp ~/Downloads/google-services.json platforms/android

Build The Android App

You should now be ready to build your Android app.

cordova build android
cordova run android

When your app starts you should see an Alert with your device’s registrationId (Device Token).

You can copy the registrationId from your Chrome Inspect console.

Save your registrationId to test push notifications on your device.

Create Your Amazon SNS App and Test Push Notifications

Navigate to your Amazon SNS App Console.

Click “Create platform application” and fill out the form. Your API Key is the Service API Key from the Add Mobile interface. Click “Create platform application” to continue.

Select the Amazon SNS app your just created. Then click “Create platform endpoint”.

Fill our the form. The “Device token” is the registrationId that you copied from the Chrome Inspect console in a previous step. Click the “Add endpoint” button to continue.

Back in the list, click on the ARN for the Android App you created.

Select the endpoint you want to push a notification to, and click “Publish to endpoint”.

Important: first, close the app on your device. This will allow you to test that the push notification is received even is the user is not present in your application.

After you have closed the app, create and send the following test message in JSON format and click the “Publish message” button.

{
“GCM”: “{ \”notification\”: { \”text\”: \”test message\” } }”
}

Note: Android platforms lower than 8.0 may require a different JSON payload, where notifications is swapped for data. You can read more about this issue on Github, and on StackOverflow.

{
“GCM”: “{ \”data\”: { \”text\”: \”test message\” } }”
}

You should see confirmation starting with: “Message published…”

Within seconds, you should see a badge appear above your app’s home-screen Icon. Also, notice the white square in the top left? This is an indicator that you have a new notification for your app. usually you would replace this with your app Icon.

If you roll down the notification blind, you will see the notification in the list. Notice the little grey square on the left? That is where your app Icon should go.

If you tap on the notification, it will take you into the app. If you remember the iOS steps, your push notification would be replayed inside your app. This is not happening in Android. Instead, you will have to send a second notification.

Now that the app is open, if you send the same payload as you did in the step above, you should see the following alert showing you the notification message that you pushed from Amazon SNS.

Note: This is a caveat of using notification instead of data in the SNS push notification payload. I am currently learning how to work around this and I plan to update the document when I have a solution to push a single notification to an Android 8.0 device and make it register in the background and foreground respectively.

Congrats! You can now send remote push notifications to Android from your Amazon SNS Console.