Updates to My Cordova Push Sample and new Cordova Push Plugin

UPDATE (11/3/2015): The updates to my Cordova push notification sample has been merged into the source fork of the Mobile Services samples GitHub repo.

As folks may remember, I published a Cordova push notifications sample for Azure to support my MSDN Magazine article: Microsoft Azure - Push Notifications to Cordova Apps with Microsoft Azure. It has been almost a year since I wrote that article (which was published in Jan 2015), and since then the article has gone out of date. Being used to writing for MSDN or azure.com, I was saddened to realize that I am not able to update this MSDN Magazine article as I can most other content on a microsoft.com web property. Fortunately, I am still able to update the sample project itself, which I have now done.

Updating the Project to Visual Studio 2015

The original sample (and article) was created using Apache Cordova Tools for Visual Studio 2013, which is no longer the happy path for Cordova apps using Visual Studio. There have been some significant (and breaking) changes to Cordova tools between 2013 and 2015, including re-rationalizing the Cordova project to become much more of a standard Cordova project, which you can now build using conventional Cordova command line tools. In fact, there are lots of CI options for VS Cordova projects now, as you can read about in the docs.

Anyway, I updated my project to Visual Studio 2015 and it’s now merged into the Mobile Services sample repository.

There’s a Cool New Push Plugin for Cordova/PhoneGap

While updating the sample, I discovered that the classic PushPlugin we’ve all been using to support push notifications on Cordova has been deprecated. There’s now a new push plugin, which you can find here: https://github.com/phonegap/phonegap-plugin-push

Needless to say, when I discovered this I also updated the sample to use this most recent (and supported) push plugin. I was happy to discover that the new plugin is much more platform agnostic than the old one way. By switching to the new plugin, I was also able to reduce the amount of code required for push by about 40% (103 lines to 61 lines of code). For example, here’s the code that initializes the plugin and requests the handle from either APNS or GCM:

 pushNotification = PushNotification.init({
    "android": { "senderID": GCM_SENDER_ID },
    "ios": { "alert": "true", "badge": "false", "sound": "false" }
});

(Note that WNS is also supported by the plugin (just also pass "windows": {} to the init function), it’s just not supported by the Mobile Services plugin.)

The new plugin is event based, so you simply register for the registration and notification events. The registration handler is where you register with Notification Hubs using the handle. My client code here is still platform-specific because of the Mobile Services plugin:

 pushNotification.on('registration', function (data) {
    // Get the native platform of the device.
    var platform = device.platform;
    // Get the handle returned during registration.
    var handle = data.registrationId;
    // Set the device-specific message template.
    if (platform == 'android' || platform == 'Android') {
        // Template registration.
        var template = '{ "data" : {"message":"$(message)"}}';
        // Register for notifications.
        mobileServiceClient.push.gcm.registerTemplate(handle,
            'myTemplate', template, null)
            .done(registrationSuccess, registrationFailure);
    } else if (device.platform === 'iOS') {
        // Template registration.
        var template = '{"aps": {"alert": "$(message)"}}';
        // Register for notifications.            
        mobileServiceClient.push.apns.registerTemplate(handle,
            'myTemplate', template, null)
            .done(registrationSuccess, registrationFailure);
    }
});

(There’s also a platform agnostic Cordova plugin for Notification Hubs, but it doesn’t support templates, which is a really nice to have for Cordova apps. Sad smile)

In my sample, the notification event is handled the same way on all platforms:

 pushNotification.on('notification', function (data) {
    // Display the alert message in an alert.
    alert(data.message);
    // Reload the items list.
    app.Storage.getData();
});

There are other fields on data, depending on the platform itself—you can check out the push plugin documentation for more info.

Overall impression: I’m not a JavaScript guru, but using this new plugin seems to yield much cleaner and more manageable code.

Whitelist Plugin is Now Required

One final thing that I discovered (and what hung me up the longest) is that the latest version of Cordova won’t connect to Azure using XHR requests. By working through the error messages, I figured out that I needed to use the Whitelist plugin and define, via policies, what code can run and what remote requests are allowed. Basically, I has to add this code to my index.html page to enable the app to connect to my mobile service:

 <meta http-equiv="Content-Security-Policy" 
        content="connect-src 'self' https://*.azure-mobile.net;">

Hopefully, the updated sample will help get folks moving in the right direction again with Azure push notifications and Cordova apps.

Cheers!

Glenn Gailey