Special connect() issue 2014

Volume 29 Number 12A

Microsoft Azure : Push Notifications to Cordova Apps with Microsoft Azure

Glenn Gailey

As mobile devices proliferate and become a ubiquitous part of our daily existence, consumers expect more and more from their mobile apps. Whereas it was once acceptable for your mobile app to simply connect to the cloud to get the latest stock quote or to store user-generated data, users now expect your app to alert them when events occur—such as when their stock hits a certain price or when their team scores. Today, all native device platforms support push notifications, which enables you to interact with your users nearly in real time.

I’ll demonstrate the basics of leveraging the Microsoft Azure platform to send push notifications to apps developed by using the Visual Studio Tools for Apache Cordova. I’ll start with an existing Cordova sample app project, create and configure the needed services, and then modify the app to register for push notifications, all in Visual Studio. I’ll focus on sending push notifications to an Android app, but the completed Cordova app sample supports the Android and iOS platforms. I’ll show how to use the Android emulator, not because it’s great (it’s not), but because it does support push notifications. I recommend using an Android device rather than the emulator if you can. (Note that sending push notifications to an iOS device requires both a physical device and an Apple Developer account, and that the Mobile Services plug-in doesn’t currently support Windows Phone.)

To use the Visual Studio 2013 tooling highlighted in this article, you need to have Update 4 installed. You also need Visual Studio Tools for Apache Cordova (aka.ms/uopu9r), which is also included in Visual Studio 2015 Preview. For a more comprehensive overview of these tools, see the article, “Write Hybrid Cross-Platform Apps in Visual Studio with Apache Cordova”, in this issue.

Finally, you’ll need an Azure account. If you don’t have an account, you can sign up for an Azure trial and get up to 10 free mobile services that you can keep using even after your trial ends. For details, see the Azure Free Trial page (aka.ms/qepjcc). 

How Push Notifications Work

Regardless of the native device platform, all push notification architectures are REST-based, whereas the details are platform-­specific. Figure 1 shows the service architecture required to send push notifications using Azure.

Push Notification Services Architecture
Figure 1 Push Notification Services Architecture

As you can see in Figure 1, the key to a push notification architecture is the platform notification service (PNS). This device-platform-specific service is responsible for sending messages to the native device, and it’s actually the device that handles the notification, not the app. You can see in Figure 1 that a back-end service is also required to send notifications to the device (this is where Azure comes in). In most cases, the back-end service must authenticate with the PNS to be able to send notifications, which is done to prevent malicious use of the PNS. The basic process of sending a push notification goes like this:

  1. The mobile app contacts the PNS to request a handle, which the service uses to identify the device. These handles aren’t durable and need to be managed and regularly refreshed.
  2. The app sends the handle to its back-end service, where it’s stored, usually with other data that enables the service to correctly target the device. As you’ll see, Azure is great for this.
  3. When sending a push notification, the back-end service sends a request to the notification service, which includes the handle and the message, in a platform-specific format (usually JSON or XML).
  4. The PNS authenticates the request and sends the requested message to the specific device, which is identified by the provided handle.

Each native device platform has its own PNS. This means when you create a cross-platform app using Cordova and want to send messages, you must provision your app with one or more of the following services:

  • Apple Push Notification Service (APNS) for iPad and iPhone devices
  • Google Cloud Messaging service (GCM) for Android devices
  • Windows Notification Service (WNS) for Windows devices
  • Microsoft Push Notification Service (MPNS) for Windows Phone devices

The push notification plug-in for PhoneGap (aka.ms/xltv38) is used to register your Cordova app with the native device’s PNS. However, even with this convenient plug-in, you still have to both manage registrations for your app on the various platforms you support and send a given message across all of those disparate platforms. On top of all of this, you still need to create and maintain a back-end service that sends out the notifications. Fortunately, Azure comes to the rescue by providing both a simplified way to register for and manage device registrations, as well as a convenient back-end service from which to send notifications to your Cordova app.

Why Use Azure for Push Notifications?

There are two services in Azure designed specifically to make it easy to send push notifications to your cross-platform mobile device apps: Azure Notification Hubs and Azure Mobile Services.

Notification Hubs A scalable, cross-platform solution for sending push notifications to mobile devices, Notification Hubs works well with Cordova apps. Notification Hubs manages the registrations with each PNS. More important, Notification Hubs lets you create template registrations so you can send messages to all registered devices, regardless of platform, with only a single line of code. You can also use tags to send targeted notifications only to devices with specific registrations. For more information about Notification Hubs, see the Azure Web site at aka.ms/nkn4n4.

Mobile Services Designed specifically to support mobile apps, Mobile Services integrates with Notification Hubs. When you create a new mobile service, a new notification hub is automatically provisioned for you. As of the writing of this article, even a mobile service running in the Free Tier allows 1 million pushes per month free of charge. In addition to push notifications, Mobile Services also provides simple storage for your app’s data in Azure SQL Database and authentication with popular providers, such as Facebook, Google, Azure Active Directory, Microsoft Account and Twitter. For more information about Mobile Services, see the Azure Web site at aka.ms/az48v5.

Because Mobile Services integrates with Notification Hubs, you can register for push notifications using the Mobile Services client. There’s no need to deal with the Notification Hubs access policies or connection strings.

As of this writing, the Mobile Services client only supports registration for iOS and Android apps. If you also need to support your Cordova app on Windows Phone using MPNS, see my blog post, “Push Notifications to PhoneGap Apps Using Notification Hubs Integration,” at aka.ms/r197ab.

Get the TodoList Sample App

Mobile Services is about connecting your mobile apps—including Cordova-based apps—to Azure for storage, authentication and push notifications. As such, it doesn’t really matter which app I use to demonstrate push notifications, just as long as it’s a Cordova app. There are several Cordova-based Todo sample app projects published by the Visual Studio folks, each using a different JavaScript framework. You can find these Visual Studio-based Cordova samples at aka.ms/dxrr30.

Although AngularJS is arguably the more popular framework, the AngularJS version of the Todo sample demonstrates using the Mobile Services REST APIs for remote data storage. The Backbone­JS sample uses the Mobile Services plug-in, so extending this sample to add push notifications is more straightforward. Thus, I chose to use the BackboneJS version of the sample (aka.ms/sffl1f). Regardless of the JavaScript framework you use for your app (if any), the same basic steps apply.

At this point, you should open the project’s index.html file and delete or comment out the existing Mobile Services references, which look like this:

<script src="http://ajax.aspnetcdn.com/ajax/mobileservices/
  MobileServices.Web-1.1.3.min.js"></script>
<script src="services/mobile services/todolist-xplat/service.js"></script>

You should also probably delete the entire existing \services folder, which contains the original sample’s service.js file. This will help to avoid confusion between multiple MobileServiceClient variables later on. In the next section, you’ll use Visual Studio to create a new mobile service and connect it to your Cordova app. You’ll also add the PushPlugin, device and console plug-ins to the project.

Create the Back-End Azure Services

Visual Studio makes it easy to provision the Azure services you need, and you can do it right from the IDE. Next, I’ll show how to create a new mobile service right from Visual Studio (assuming you have an active Azure subscription).

In the Visual Studio Solution Explorer, right-click the project, then click Add | Connected Service. In the Services Manager, click Create service. Set the following fields in the Create Mobile Service dialog, shown in Figure 2, then click Create:

  • Subscription: This is your Azure subscription.
  • Name: This is the name of your new mobile service, which must be unique across Azure and which becomes part of the service’s URL. A red X is displayed when the name you entered isn’t available.
  • Runtime: This app uses a JavaScript (Node.js) back end, which just makes more sense for JavaScript programmers than a .NET back end (ASP.NET Web API project).
  • Region: The location of your mobile service—ideally in the same location as your SQL Database.
  • Database: Either choose an existing database in the same region or create a new database, ideally a free one. When you choose an existing database, tables belong to the schema that’s the mobile service name, so there’s no risk to your current data.
  • Server user name and Server password: These are important credentials, so keep them safe. Mobile Services won’t need them again, but you will when you want to use this database for something else, such as to support another mobile service.

The Create Mobile Service Dialog
Figure 2 The Create Mobile Service Dialog

When you click Create, a new mobile service is provisioned along with a new notification hub. Back in the Service Manager dialog, select the new service and click OK. This adds a version of the Mobile Service plug-in and the InAppBrowser plug-in, which Mobile Services uses for authentication, to the Cordova project. It also adds and opens a new code file, such as todolist-cordova.js, that defines the MobileServiceClient instance used to connect to the mobile service. Leave this file open; you’ll make updates here later.

Next, you need to create a new TodoItem table in your SQL Database that the app can use to store items. Open Server Explorer, expand the Azure node and then the Mobile Services node, right-click the mobile service and select Create Table. Type TodoItem for Table name, then click Create. A new TodoItem table is added under the mobile service node in Server Explorer. This node corresponds to a new SQL Database table, which is exposed as a new table in your mobile service.

At this point, you need to update the default insert script exe­cuted by Mobile Services when an insert is made into the new table. In Server Explorer, expand the TodoItem table you just added, open the insert.js file and replace the existing insert function with the code shown in Figure 3.

Figure 3 The Script Executed When Items Are Inserted into the TodoItem Table

function insert(item, user, request) {
  // Execute the request and send notifications.
  request.execute({
    success: function () {
      // Create a template-based payload.
      var payload = '{ "message" : "New item added: ' + item.text + '" }';
      // Write the default response and send a template notification
      // to all registered devices on all platforms.           
      push.send(null, payload, {
        success: function (pushResponse) {
          console.log("Sent push:", pushResponse);
          // Send the default response.
          request.respond();
        },
        error: function (pushResponse) {
          console.log("Error Sending push:", pushResponse);
          // Send the error response.
          request.respond(500, { error: pushResponse });
        }
      });
    }
  });
}

The code in Figure 3 calls the send method on the push object to send a template-based push notification to all registered devices. Instead of passing a null to the first parameter (tags) as in this case, you can also pass a tag value or array of tags. When you use tags, Notification Hubs will only send notifications to a device whose registration contains one of those tags. For more on tags, see aka.ms/cwr4l4.

Finally, you need to navigate to the Azure Management Portal Web site so you can register your app’s PNS credentials, which you’ll create in the next section. In Server Explorer, right-click the node for your mobile service in Azure, then click Open in Management Portal and sign in to the portal. At this point, you should be in the quickstart tab (denoted by a symbol only) for your new mobile service. Click the Push tab and notice the name of the notification hub used by your mobile service at the top of the page. You’ll need to know this if you have to troubleshoot your notification hub in Visual Studio (as you’ll see later on). Scroll down to GCM settings at the bottom of the page. This is where you set the GCM API key once push notifications are provisioned.

Provision the Google Cloud Messaging Service

The most time-consuming part of configuring push notifications is usually provisioning the app with the PNS. Thankfully, this provisioning need only be done once for a given app and platform. For Android, you need a Google account to provision your Cordova app with GCM at the Google Developers Console Web site (aka.ms/wt80js). Once signed in, click Create Project, specify a Project Name and (optionally) your own unique Project ID, accept the terms, and then click Create. Once created, the new project is displayed. Write down the Project Number value shown at the top of the page; you’ll need it later on.

Next, expand APIs & auth, click APIs, scroll down to Google Cloud Messaging for Android, enable it and accept the terms of service. Now, under APIs & auth, click Credentials, under Public API access click Create new Key, click Server key and then Create. Write down the API key value. Back in the Azure Management Portal, enter the API key under the “google cloud messaging settings” section, then click Save.

The API key is now set and Notification Hubs can now use GCM to send push notifications to your app. If you have trouble provisioning GCM, or if the Web site changes, you can always find the latest, detailed steps for provisioning GCM in the article, “How to Enable Google Cloud Messaging,” on the Azure Web site at aka.ms/po7r8n. You can also find the equivalent steps for provisioning an iOS client with APNS in the article, “How to Enable Apple Push Notifications,” on the Azure Web site at aka.ms/vooydc. Note that because Notification Hubs is an independent service, other back-end services can also use this registration to send notifications to your app.

Update the Client to Register for Notifications

The last thing you need to do is to update the downloaded TodoList sample project to register for push notifications with Azure when the app starts. First, you need to add the required plug-ins. In Solution Explorer, double-click the config.xml project file to open it in the configuration designer and choose the Plugins tab. Under Core, add the Device, Console and Geolocation plug-ins. If the Azure Mobile Services plug-in has already been installed, click Remove to uninstall it—you need to install a more recent version that supports push notifications. Next, click Custom, select Git, enter the following URL to the Azure Mobile Services plug-in repository, and then click Add:

https://github.com/Azure/azure-mobile-services-cordova.git

This installs the most recent version of the plug-in that contains the Mobile Services client library. Repeat the previous step to add the PushPlugin to the project by using the following repository URL:

https://github.com/phonegap-build/PushPlugin.git

Figure 4 shows how simple Visual Studio now makes it to add any valid Cordova plug-in to your project.

Adding the PushPlugin Plug-in to the App Project
Figure 4 Adding the PushPlugin Plug-in to the App Project

Open the project file that was created when you added the Mobile Services connection to your project (the one with the name such as todolist-cordova.js, where todolist-cordova is the name of the service). Save a copy of the existing MobileServiceClient constructor, which contains the URL for your mobile service and application key (so they don’t get overwritten), then replace this generated code with the code shown in Figure 5.

Figure 5 Code that Registers with Azure for Push Notifications When the App Starts

var GCM_SENDER_ID = '<your_project_number>'; // Replace with your own ID.
var mobileServiceClient;
var pushNotification;
// Create the Azure client register for notifications.
document.addEventListener('deviceready', function () {
  mobileServiceClient = new WindowsAzure.MobileServiceClient(
    'https://todolist-cordova.azure-mobile.net/',
    'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX');
  // Define the PushPlugin.
  pushNotification = window.plugins.pushNotification;
  // Platform-specific registrations.
  if (device.platform == 'android' || device.platform == 'Android') {
    // Register with GCM for Android apps.
    pushNotification.register(successHandler, errorHandler,
      {
        "senderID": GCM_SENDER_ID,
        "ecb": "onGcmNotification"
      });
  }
});
// Handle a GCM notification.
function onGcmNotification(e) {
  switch (e.event) {
    case 'registered':
      // Handle the registration.
      if (e.regid.length > 0) {
        console.log("gcm id " + e.regid);
        if (mobileServiceClient) {
          // Template registration.
          var template = "{ \"data\" : {\"message\":\"$(message)\"}}";
          // Register for notifications.
          mobileServiceClient.push.gcm.registerTemplate(e.regid,
            "myTemplate", template, null)
            .done(function () {
              alert('Registered template with Azure!');
            }).fail(function (error) {
              alert('Failed registering with Azure: ' + error);
            });
          }
        }
        break;
      case 'message':
        if (e.foreground) {
          // Handle the received notification when the app is running
          // and display the alert message.
          alert(e.payload.message);
          // Reload the items list.
          refreshTodoItems();
        }
        break;
      case 'error':
        alert('Google Cloud Messaging error: ' + e.message);
        break;
      default:
        alert('An unknown GCM event has occurred');
        break;
  }
}

The code in Figure 5 requests a registration ID from GCM, then uses the returned registration ID to either create or update a Notification Hubs registration. Note that Figure 5 only contains GCM code required for Android, whereas the accompanying project download contains code for both Android and iOS. To get this code to run in your project, replace the MobileServiceClient constructor with the saved one that was added by the Visual Studio tools. Also, set GCM_SENDER_ID to the project number of your app in Google Developers Console.

Configure the Android Emulator for Push Notifications

Unlike the iOS simulator, you can receive push notifications on the Android emulator, provided you perform a few extra configuration steps. You basically need to use the Google APIs and add a Google account. When using a physical Android device, you can skip these steps and go to the next section to run and test your app. (Again, if possible, you should really try to run on a physical Android device—the emulator that ships with the Android SDK is excruciatingly slow, though it does work.)

From a command prompt, type “android avd,” which displays the Android Virtual Device (AVD) Manager. You should have at least one AVD available, which is sometimes named MyEmulator. If you don’t have an AVD, you need to create one. Select your AVD, click Edit, then set the Target to Google APIs and click OK. Click Start to run this emulator. On the emulator, click the apps icon, then click Settings. Scroll down to Accounts, click Add account, click Google, and add a new or existing account to the emulator. With the Google account added, you can receive notifications on the emulator.

Once you’ve added a Google account on the emulator, you should plan to keep the emulator running (unless you’ve enabled snapshots in the emulator options). Otherwise, the state of the device won’t be maintained when you restart the emulator, and you’ll have to re-add a Google account to be able to receive notifications again.

Run the App and Generate Push Notifications

The first time you run the app, a new registration is created in your notification hub. On subsequent startups, the existing registration is updated with the most recent registration ID returned by the GCM. With the Android emulator selected, press F5 to start and run the app. Visual Studio starts a Cordova build targeted at the Android platform, and the app is deployed to and started on the running emulator (it also starts the emulator, if needed). After the app loads, an alert is displayed after the app successfully registers (or updates the registration) for push notifications with Azure. When you add a new item, the onGcmNotification function (shown in Figure 5) handles the incoming message, when the app is running, and displays the message in an alert.

When the app isn’t running, the notification ends up in the status bar. Figure 6 shows the notification appearing as an alert (on the left) and in the status bar.

Notification Messages as an Alert (Left) and Appearing in the Status Bar
Figure 6 Notification Messages as an Alert (Left) and Appearing in the Status Bar

You can test this behavior by switching out of the app right after sending. Or, if there isn’t enough time to do this, you can add a delay in the insert script before the send method is called. When you click the notification in the status bar, the app is started.

Another way to demonstrate this is by sending a test notification to your app.

Troubleshoot Registrations by Sending Test Notifications

Because several services and various registrations are involved, it can be tricky to troubleshoot push notifications. Fortunately, diagnostic functionality for Notification Hubs is built right into Visual Studio 2013. From the Server Explorer, expand Azure and then Notification Hubs, and you should see your notification hub listed. Double-click this item and you will see a diagnostic page open right in Visual Studio (see Figure 7). This page has the following two tabs:

  • Test Send: This lets you compose and send messages using the notification hub. You can target specific native device registrations or, in this case, a template registration. When you click Send, the specific notification is sent; the result, as logged by Notification Hubs, is shown in Message Result.
  • Device Registrations: This enumerates all registrations that currently exist in the notification hub. From this tab, you can delete registrations or update the tags collection for a registration. On this tab, you should see at least one registration, which was just added when you started your app.

Notification Hubs Diagnostic Page
Figure 7 Notification Hubs Diagnostic Page

Remember, when you send a test notification from Visual Studio and the app isn’t running, the message shows up in the status bar. Had the app been running, an alert would’ve been raised instead (as was shown in Figure 6).

You can find much of the same push notification test functionality in the Notification Hubs tab at the Azure Management Portal (manage.windowsazure.com), but it’s great to be able to test and do some basic debugging right in the Visual Studio IDE.

Simplified Notifications

To review, mobile users now more than ever expect their devices to keep them up-to-date with the latest on their interests and what’s going on around them. Your mobile app needs to be able to notify your customers, in near-real time, about updates in the important data that your app provides. In a cross-platform app, such as a Cordova-based app, dealing with four or more different native push notifications platforms can be tricky to set up and manage.

With its support for template-based registrations, Notification Hubs is a great solution for sending push notifications to Cordova apps. Push functionality is enabled in your app by the PushPlugin. Combined with the data storage and authentication facilities of Mobile Services, the Azure platform is convenient for supporting Cordova apps. For more information about using Azure to support cross-platform apps, see the Azure documentation topic, “Supporting Multiple Device Platforms from a Single Mobile Service,” at aka.ms/w7oq0y. Not only is Visual Studio a great platform for developing Cordova apps, it’s also a great tool for creating and managing Azure for your Cordova apps.


Glenn Gailey is a programmer writer and 14-year Microsoft veteran who has created documentation and samples for Azure Mobile Services, Notification Hubs, WCF Data Services, OData, ADO.NET Entity Framework, SQL Server Replication and SQL Server CE. Reach him at glenn.gailey@microsoft.com or via Twitter at ggailey777.

Thanks to the following Microsoft technical experts for reviewing this article: Suresh Jayabalan, Mike Jones and Piyush Joshi