Sending & Receiving Push Notifications in Ionic Apps

A brief overview

Often times when you're building a mobile app you will want to alert users that they should open your app. Whether it's a like on their photo or a reminder that today is their anniversary (for the record, this example is definitely not from my own personal experience), push notifications serve an important purpose in the lifecycle of mobile applications. However, if you've done any research on push notifications, you know that the nuts and bolts of how push notifications work under the hood are not particularly straightforward. The good news is that there are some awesome plugins and services that make sending push notifications absolutely painless and we'll be covering them thoroughly in this course.

How push notifications work

Lets first get a basic understanding of how Apple's APNS and Google's GCM push notification architectures work. It's important to know what happens under the hood even though we'll be using services that abstract away this complexity for us.

The video above explains the high level overview of how this all works, but if you're interested learning more, the following resources from Google and Apple should answer any of the remaining questions you have:

Needless to say, these are not the most intuitive services to directly work with, and we highly recommend you use the amazing services that have been built to make them easier to implement. Without further ado, lets dive into the real meat of implementing push notifications in your apps.

Implementing push notifications in your app

A couple of years ago, services began emerging that brought the simplicity of typical pub/sub systems to push notifications. Instead of having to manually track your user's phone IDs individually, these services allow you to simply subscribe your users to desired channels to receive push notifications from.

For example, if a user wants to be notified when a course on Javascript is published on Thinkster, we could subscribe them to a channel called "javascript" that thousands of other users could also be subscribed to. However, to trigger a push notification to all of these users would only take one line of code - simply publish a push notification to the "javascript" channel and all of our users will receive it. Compare this to querying your database that contains your user's phone IDs, segmenting which users want to be notified about Javascript, and then sending out notifications individually for each of them to APNS/GCM. Yuck!

There are a few services out there that provide this pub/sub functionality, but at this point in time, we highly recommend using Parse for managing your push notifications. Here's why: - It's widely adopted and battle hardened from usage across 100,000+ apps - It's free to send an unlimited number of push notifications as long as you have < 1 million users (!!!) registered on your app (after that you have to pay a measly five cents per thousand additional users) - Their plugins and API are insanely easy to use

We will do an overview of a couple other services available to you later on in this course, but in general the setup across these various services are very similar!

Preparing your environment

The other thing you need to know when developing for iOS is that Apple does not let you send push notifications to apps running in the emulator; you have to use a real device. We recommend that you test any functions the push notification will invoke in the emulator, and then when your app is built out you will need to load your app on a real device to ensure push notifications are actually being received.

Setting up Parse

To get this project working for your app specifically, we need to swap your unique keys and identifiers:

At this point, your project should be runnable! There are really only two things you need to call when using Parse: initialize, which ensures that this device is registered for push notifications, and subscribe, which will subscribe this specific phone to any channel you provide. There is also a third method getInstallationId that will return the installation ID of this Parse user, but it's only useful if you're deep diving into some of Parse's more advanced features.

Lets take a quick moment to review the code connecting our app to Parse in www/app.js:

window.parsePlugin.initialize(appId, clientKey, function() {
      console.log('Parse initialized successfully.');


      window.parsePlugin.subscribe('SampleChannel', function() {
        console.log('Successfully subscribed to SampleChannel.');


          window.parsePlugin.getInstallationId(function(id) {
            // update the view to show that we have the install ID
            console.log('Retrieved install id: ' + id);

              /**
               * Now you can construct an object and save it to your own services, or Parse, and corrilate users to parse installations
               * 
               var install_data = {
                  installation_id: id,
                  channels: ['SampleChannel']
               }
               *
               */

          }, function(e) {
            console.log('Failure to retrieve install id.');
          });

      }, function(e) {
          console.log('Failed trying to subscribe to SampleChannel.');
      });

    }, function(e) {
        console.log('Failure to initialize Parse.');
    });

This isn't terribly complex to look at, but do note that it's being run after all of the Cordova apps have been loaded in $ionicPlatform.ready. This is important, as we don't want to call window.parse methods if the Parse plugin isn't available to us yet! Another thing to note is that this code will be fired every single time the app is opened. You can call initialize and subscribe to the same channel as many times as you want without it affecting the user, your Parse account, or APNS/GCM. In fact, it's probably best that you do this to ensure that the user didn't accidentally turn off push notifications for your app since the last time they used it.

Since this app is now subscribed to the 'SampleChannel' Parse channel, that means we can now send push notifications to it. As seen in the video above, you can do this through the Parse Push dashboard by specifying 'SampleChannel' as the target. However, if you're building a production ready application, you'll probably want to sending push notifications programmatically from your server via Parse's REST API.

Sending push notifications through channels is not only great for groups of users, but you can also use if for individual users as well. For example, you can programmatically create unique channels for every single one of your users by just subscribing them to a channel with their user ID appended to the end of it (i.e. window.parsePlugin.subscribe('thinkster-user-' + userID)). Even if your users sign in on new devices, you can continue sending them push notifications just by knowing their user ID!

Other options

It is worth mentioning that a new service from Ionic is coming out of beta soon for push notifications that sounds totally awesome. Once this is released to the public, I will be updating this course accordingly!

Roll your own

If you want to integrate with the raw APIs for APNS and GCM, I highly recommend checking out Holly Schinsky's posts on Push notifications with ngCordova and Ionic, push notifications with Cordova on Android, and push notifications with Cordova on iOS. Consider following her on Twitter too, as she posts lots of great stuff for hybrid app developers!

Final thoughts

If you're interested in staying in the loop on updates to this course and hybrid apps in general, follow me on Twitter! If you find anything that should be fixed or have any suggestions, don't hesitate to reach out on Twitter or via email at eric@thinkster.io!