Last weeks I’ve been struggling to build an Ionic app with push notifications. There is some documentation about it and some blogs by Holly Schinsky: http://devgirl.org/2014/12/16/push-notifications-sample-app-with-ionic-and-ngcordova/ but it still took me quite some time to get it working on my iPhone.
In this blog I want to share my findings and create a most basic Ionic app that can register for and receive push notifications on iOS devices.
Prerequisites:
- You need an Apple Developer Account to sign your app. (It’s not working in the Ionic Viewer app for iPhone).
- Installed node.js and Ionic, see http://ionicframework.com/getting-started/
- A Mac computer with Xcode installed for building the app.
- A Provisioning Profile and pem files.
For the creation of the provisioning profile and pem files you can check: http://www.raywenderlich.com/32960/apple-push-notification-services-in-ios-6-tutorial-part-1#attachment_3502
It’s a very good tutorial, so you should be able to get this done 🙂
So let’s get started.
The app we will create is called PushIt, in the first part the app itself is created. It’s an empty app but the main goal is to get the device token. This token is needed to send notifications later on.
Create a blank ionic app by running
ionic start PushIt blank
Move to the app folder
cd PushIt
Install ngCordova
bower install ngCordova
Install the cordova push plugin
cordova plugin add https://github.com/phonegap-build/PushPlugin.git
Get the PushNotification.js file created in the new plugins folder at plugins\com.phonegap.plugins.PushPlugin\www and copy it to the www\lib folder of you Ionic application. Add references to the ngCordova and pushnotification javascript files in the index.html file in the www folder
... <!-- ionic/angularjs js --> <script src='lib/ionic/js/ionic.bundle.js'></script> <!-- add these 2 lines, check if the files exist --> <script src='lib/ngCordova/dist/ng-cordova.min.js'></script> <script src='lib/PushNotification.js'></script> <!-- cordova script (this will be a 404 during development) --> <script src='cordova.js'></script> ...
Open the config.xml in the root of your app file and make sure you add your Apple bundle Identifier (If you like you can change the description and author as well).
<?xml version='1.0' encoding='UTF-8' standalone='yes'?> <widget id='com.mydomain.pushit' version='0.0.1' xmlns='http://www.w3.org/ns/widgets' xmlns:cdv='http://cordova.apache.org/ns/1.0'> <name>PushIt</name> <description> An Ionic Push Notification Demo. </description> <author email='chris.hagens@gmail.com' href='https://chriztalk.wordpress.com/'> Chris Hagens </author> <content src='index.html'/> <access origin='*'/> <preference name='webviewbounce' value='false'/> <preference name='UIWebViewBounce' value='false'/> <preference name='DisallowOverscroll' value='true'/> <preference name='BackupWebStorage' value='none'/> <feature name='StatusBar'> <param name='ios-package' value='CDVStatusBar' onload='true'/> </feature> </widget>
Update the app.js (it’s in the www/js folder)
angular.module('starter', ['ionic', 'ngCordova']) .run(['$rootScope', '$ionicPlatform', '$cordovaPush', function ($rootScope, $ionicPlatform, $cordovaPush) { $ionicPlatform.ready(function () { // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard // for form inputs) if(window.cordova && window.cordova.plugins.Keyboard) { cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true); } if(window.StatusBar) { StatusBar.styleDefault(); } var iosConfig = { 'badge': true, 'sound': true, 'alert': true, }; $cordovaPush.register(iosConfig).then(function(result) { // Success -- send deviceToken to server, and store for future use console.log('result: ' + result) $rootScope.deviceToken = result; //$http.post('http://server.co/', {user: 'Bob', tokenID: result.deviceToken}) }, function(err) { alert('Registration error: ' + err) }); $rootScope.$on('$cordovaPush:notificationReceived', function(event, notification) { if (notification.alert) { navigator.notification.alert(notification.alert); } if (notification.sound) { var snd = new Media(event.sound); snd.play(); } if (notification.badge) { $cordovaPush.setBadgeNumber(notification.badge).then(function(result) { // Success! }, function(err) { // An error occurred. Show a message to the user }); } }); }); }]);
To show the devicetoken, make following changes to index.html located in the www folder
... <ion-pane> <ion-header-bar class='bar-stable'> <h1 class='title'>PushIt</h1> </ion-header-bar> <ion-content> deviceToken: <input value='{{deviceToken}}' type='text'/> </ion-content> </ion-pane> ...
Add the ios platform to your Ionic application:
ionic platform add ios
Next you can open the xcode project created in platform/ios folder called PushIt.xcodeproj.
Attach you phone to your computer and set your iPhone as the active scheme (right next to the build and run button at the left top) and run the application.
You should now be able to get your deviceToken from the app or from the output window in Xcode.
For a real world app you should store this somewhere on your server, for now we just write it down somewhere.
We will need this to send an actual Push notification.
Create a file called SendNotification.js and add you deviceToken, pem files and password:
var http = require('http'); var apn = require('apn'); var url = require('url'); var deviceToken = '####################'; // ** NEED TO SET TO YOURS var myDevice = new apn.Device(deviceToken); var note = new apn.Notification(); note.badge = 1; note.contentAvailable = 1; note.alert = 'PushIt works:\n Congratulations! \u270C\u2764\u263A '; note.payload = {'messageFrom': 'PushIt'}; note.device = myDevice; var callback = function(errorNum, notification){ console.log('Error is: %s', errorNum); console.log('Note ' + JSON.stringify(notification)); } var options = { gateway: 'gateway.sandbox.push.apple.com', // this URL is different for Apple's Production Servers and changes when you go to production errorCallback: callback, cert: 'your-cert.pem', // ** NEED TO SET TO YOURS key: 'your-key.pem', // ** NEED TO SET TO YOURS passphrase: 'your-pw', // ** NEED TO SET TO YOURS port: 2195, enhanced: true, cacheLength: 100 } var apnsConnection = new apn.Connection(options); console.log('Note ' + JSON.stringify(note)); apnsConnection.sendNotification(note);
Make sure you installed the node modules apn and url, or install them now:
npm install apn
npm install url
Next you can send a notification by running this:
node SendNotification.js
That’s all, please let me know if you don’t get it working…
12 comments. Leave new
Hey, some of your code examples are encoded, please decode them (:
Hmm, must have been the new editor, but I decoded it.
After running on device i’m getting: Registration error: – no valid ‘aps – environment’ entitlement string found for application.
It probably has to do with your provisioniug profile, check http://stackoverflow.com/questions/27324020/no-valid-aps-environment-entitlement-string-found-for-application-on-app-store
Hi, I’m developing an iOS app with push notifications but I do not know what to do when I receive multiple notifications. I’m getting from backend all the push notifications sent to the device but I need to know if a push notification is received somehow. Is the cordova event for notifications fired even if the app is not opened sliding an incoming notification? I cannot test my app from a real device so I need help 🙁
It’s not totally clear what you mean, but the push notifications will work like any other push notification, so the app doesn’t have to be openend. For sending the notifications cordova isn’t used at all, it’s handled by the Apple Push Notification services, this will sent the notifcation to your device based on the device token.
Hello, thanks for writing this up. Following your tutorial I get ‘enabledRemoteNotificationTypes is not supported in iOS 8.0 and later.’ in Xcode debug window. Do you have this running on iOS 8?
Yes I have, you should ignore this error.
Great tutorial, I get an error ‘no valid device tokens’. I get the same token over and over again. I dont know how to reset a users device token.
Please, make a video
Great tutorial helped me thank you very much..
Everything is working fine. i have a small issue i am getting notification alert sound while app is in foreground only, i am not getting the sound when app closed.any idea?