In App Notifications with the Ionic Framework

I’m working on an app that relies heavily on the concept of in app notifications. Rather than make this app two or more times (in Java for Android, in Objective-C or Swift for iOS, in whatever Windows phones use), I have opted to go hybrid, enabling me to code in JavaScript and deploy anywhere.

Now, all this is tickety boo, except that as you might expect, working in one language for three platforms has its *ahem* caveats.

Before I go further I firstly want to say how amazingly awesome it is that the Ionic Framework even exists, let alone as an open source project that’s free to use for all. I also want to give my love and thanks to all the contributors of plugins that allow Ionic-based apps to do 90%+ of what can be done natively in app.

I can only imagine how difficult it must be to make one plugin that works on multiple platforms, in a market that is as fast paced as the mobile device industry.

Inevitably, I have hit on a few issues as I’ve been working on this app, and a large part of the reason and process behind this is to show what those problems are, and just as importantly, how I have overcome them.

Local Notifications with $cordovaLocalNotification

Sebastián Katzer
Sebastián Katzer

As mentioned, a large part of my app relies on the use of in app notifications.

The gist of the app is that a user can select one or more ‘hours’ to subscribe too / be notified about, and then the mobile device should send an alert when those hours are about to begin.

The obvious starting point here then is the Local Notifications plugin by Sebastián Katzer.

The code itself to get this working is pretty straightforward. This is in large part to the brilliant Wiki documentation that is chock full of helpful examples, coupled nicely with the official documentation – scroll to the bottom of this page for the Ionic-specific Examples section.

So now we have some code to work with:

 

This is where things started to get interesting for me, and also where things started to go wrong.

My first issue was that whilst all the examples I could find involve $scope, I didn’t have access to this as I was calling the schedule method from a Service.

My solution to this (which may be incorrect, definitely feels incorrect, and is not taking advantage of dependency injection so is hard to test), was to switch to the following:

 

This is a rough draft / proof of concept. But, importantly, it worked. And I say it worked, it took a day and a half of hacking to get it to work. It may not be pretty but by Jove it sends me some damn alerts and right now, that’s good enough.

If Only Coding Were That Easy

Of course, if it had been that simple, it wouldn’t be worth blogging about.

I strongly encourage you to make use of a README.md file in your project, making notes on how you get things to work in your project. It’s all fine and dandy today, but what happens next week, next month, or in my case, an entire year later you decide to pick the project back up and things don’t work as you remember. You may be thinking, Chris, I would just type history in to my terminal and look at what I did to make it work. Well, that’s a solution for sure, but not for many of us, especially if your wife had accidentally tipped a glass of wine over your old Macbook during the interim.

To make things trickier, as mentioned, some things that blow up on one platform, work splendidly on another. A case in point would be when you have failing dependencies that are Android specific, which allow you to run your iOS project but blow up on building your Android project. Hair loss time.

Firstly, check your Ionic info:

ionic info

Your system information:

  • Cordova CLI: 5.0.0
  • Gulp version: CLI version 3.8.1
  • Gulp local: Local version 3.8.11
  • Ionic Version: 1.0.0
  • Ionic CLI Version: 1.4.6-beta.0
  • Ionic App Lib Version: 0.0.22
  • ios-deploy version: Not installed
  • ios-sim version: 3.1.1
  • OS: Mac OS X Yosemite
  • Node Version: v0.12.4
  • Xcode version: Xcode 6.3.1 Build version 6D1002

Updating Node is pretty straightforward on Mac – just download it and run the installer.

As part of getting this to work today, I also ran:

I think that can be done as a one-liner, but I didn’t, so I am showing each one as it is in my history.

Android Specific Stuff

Quite possibly the second most time intensive part of this whole process – after debugging why Local Notifications kept blowing up – was the download and install the latest Android SDK stuff. Man. Alive. It took ages.

On Mac:

brew install android-sdk

That bit was pretty quick. Then, as prompted, run:

export ANDROID_HOME=/usr/local/opt/android-sdk

Check the path given by brew installer, as the above may not work for you.

Then:

android

This pops up the Android SDK Manager, which *should* go off and search for all the latest Android stuff that you will need to download (which takes bloody ages), and install (which takes about the same amount of time as downloading).

Android SDK on Mac OSX

I hit a bit of trouble here which will likely not affect you. As I record my training videos on a distraction free second profile, and because I am making this app as part of a course for Code Review, I couldn’t run the SDK manager from the profile I hadn’t run the brew install android-sdk command from originally. This ultimately involved switching profiles whenever I have needed to update the SDK – which is more frequently than I had anticipated (every other day so far, but then, Android M is releasing currently).

Keeping Ionic in Sync with your Installed Plugins

As mentioned, to get in app Local Notifications to work involved using a plugin.

Installing this plugin is described on the plugin authors website as:

cordova plugin add https://github.com/katzer/cordova-plugin-local-notifications

That was my initial move. There are some other suggested ways of installing this plugin on that website, and I tried all of them.

The problem was, I kept hitting on issues when trying to build for Android, which were predominantly dependency names used in the Katzer provided config.xml which were 404’ing when npm was trying to download them.

Here’s a good example of what I mean:

It would then promptly bomb out and blow up.

The important line is:

WARNING: android.support.v4 has been renamed to cordova-plugin-android-support-v4. You may not be getting the latest version! We suggest you cordova plugin rm android.support.v4 and cordova plugin add cordova-plugin-android-support-v4.

I tried the obvious – running:

cordova plugin rm android.support.v4 and cordova plugin add cordova-plugin-android-support-v4

And that kinda works. It works because it does what it says on the tin. But the issue is that it’s not you who is managing that dependency, it’s the plugin you are trying to use – in this case, it’s a dependency of the Local Notification plugin (I think, I hit so many of these that this was just the first one I found in my terminal when scrolling back).

As this is a dependency of a plugin, you can’t – directly – change this without submitting a Pull Request, waiting for that PR to be approved, merged, and then having the new version imported. I couldn’t wait that long, and I’m always reluctant to submit a PR to a project I don’t understand how to test. So, instead, I forked it.

I updated the plugins to use the new paths for the dependencies, and all was sorted – on that front. If you’re interested, click here to see the commit history.

For reference, my package.json file looks like this:

You can make ionic do the dirty work for you on keeping this file updated, just run: ionic state save – but before you do, make sure you have a back up of your package.json just in case.

The reason some of the plugins use the locator and id properties inside their own JSON object is that I added Github repo URLs instead of the package names, e.g.:

cordova plugin add https://github.com/a6software/cordova-plugin-local-notifications.git

instead of:

cordova plugin add de.appplant.cordova.plugin.local-notification

More Problems On Android

However, when building I was still hitting on another issue – this time one with an outstanding pull request.

For me, this issue occured when running ionic run android – I don’t use the emulator, I can’t seem to make the thing work for Android, so this was deploying to a real Android phone.

I applied the fix directly to my own fork, and that resolved the issue.

Don’t Be Afraid To Remove Your Platform

Seemingly the best way to ensure your project is fresh is to remove and re-add your platform whenever you make a change:

ionic platform r, android && ionic platform add android

This way, you can be sure you are getting the exact plugins you expect rather than some existing ones that may be cached / different to what you expect.

This process *should* blow up if any of your plugins have errors / unmet dependencies etc.

Other Things I Had To Do

These bits are things I did which I am unsure whether they helped, but they were done so are here for reference:

sudo chown -R {yourUsername} ~/.android

I found my ~/.android (my user’s home directory /.android dir) was owned by root. This caused the build to fail. The message was quite clear on this. Not sure how it ended up owned by root in the first place mind.

ionic browser remove crosswalk

(http://ionicframework.com/docs/cli/browsers.html)

In App Notifications Working!

android local notifications with ionic
android local notifications with ionic

Success. At last! 🙂

Shares

Published by

Code Review

Code Review

CodeReviewVideos is a video training site helping software developers learn Symfony faster and easier.

4 thoughts on “In App Notifications with the Ionic Framework”

  1. could you please help with an example for clicking on notification with app’s state ‘background’? im testing with a simple alert on clicking on notification, it works only when app is in foreground, i need a modal window to present user a form on notification click.

    1. Hi Faizan,

      I don’t have any experience of doing this either – Google / StackOverflow / Ionic forums would be best for this one.

      Sorry I couldn’t help further at this time,

      Chris

Leave a Reply

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