ChrizTalk

iOS push notifications using Ionic framework

March 4, 2015ChrizIonic12 comments
If you like it, please share it:

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…

If you like it, please share it:
Previous Post Email reports from SQL Azure Next Post Ionic/Angular server side error logging

12 comments. Leave new

Oron Ben Zvi
March 20, 2015 10:39 am

Hey, some of your code examples are encoded, please decode them (:

Reply
henkie14
March 20, 2015 3:32 pm

Hmm, must have been the new editor, but I decoded it.

Reply
Oron Ben Zvi
March 20, 2015 11:08 am

After running on device i’m getting: Registration error: – no valid ‘aps – environment’ entitlement string found for application.

Reply
henkie14
March 20, 2015 3:34 pm

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

Reply
jesus
April 8, 2015 4:33 pm

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 🙁

Reply
henkie14
April 9, 2015 11:53 am

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.

Reply
ablears
June 25, 2015 10:50 pm

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?

Reply
henkie14
September 30, 2015 3:23 pm

Yes I have, you should ignore this error.

Reply
bartvanderlaan
July 19, 2015 4:48 pm

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.

Reply
Reinner
September 23, 2015 3:14 am

Please, make a video

Reply
Munavvar
August 16, 2016 8:00 am

Great tutorial helped me thank you very much..

Reply
Munavvar
September 18, 2016 10:39 am

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?

Reply

Leave a Reply Cancel reply

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

Recent Posts

  • Ionic 3 and Firebase Facebook authentication using AngularFire2
  • Ionic 3 and Firebase authentication using AngularFire2
  • Ionic 3, Firebase and AngularFire2
  • Ionic 2 and Font Awesome using Sass
  • Using Google Fonts in Ionic 2

My Ionic 2 Theme

Please have a look at my new Ionic 2 theme.

&copy 2016 ChrizTalk