Microsoft's Windows AppStudio: Add Support For Push Notification

The purpose of this article is to show how to add support for Push Notification to a Menu App.

Scope

The purpose of this article is to show how to add support for Push Notification to a Menu App. See the last two articles:

Introduction

Push Notifications have become an integral part of any modern application, since they increase user engagement for consumer apps and the utility of enterprise apps.

To add support for Push Notification:

  • The MyMenuApp Azure Mobile Service will send the Push Notifications
  • The Menu App will receive the Push Notifications

The process of adding Push Notification to a Menu App using Azure Mobile Service can be so easy that we don´t need to understand all the process behind it. But it is important to understand at least:

  • The Windows Phone 8.1 and Windows 8.1 apps uses the Windows Push Notification Services (WNS). This service enables third-party developers to send toast, tile, badge and raw updates from their own cloud service. This provides a mechanism to deliver new updates to your users in a power-efficient and dependable way.
  • Azure Mobile Service is integrated with Notification Hubs and when the MyMenuApp Azure Mobile Service was created, in the Azure Portal, was created the MyMenuAppHub-ns Notification Hub.

    “An Azure Notification Hubs provide an easy-to-use infrastructure that enables you to send mobile Push Notifications from any backend (in the cloud or on-premises) to any mobile platform.”: Notification Hubs Overview.

A Menu app does not require user authentication, for this reason all notifications sent will be received by all users.
Note: For applications that use authentication, the process is a little different, because the User X will not receive the notification for User Y and vice-versa. A good example are the notifications in Facebook.

Send Push Notification

To send Push Notification, the AppStudio.Menu.BackEnd must be changed and we should use the Service.Push.SendAsync method to send the notifications.

In table controllers, we have the Service property that contains a Push property that allows us to send the notification, here are the options for it:



The notification payload is one of WindowsPushMessage, ApplePushMessage, or TemplatePushMessage.

In the MyMenuApp Azure Mobile Service, we will notify the user when an object is inserted or updated. For it, in each controller we will change the Post and Patch methods.

Defining the messages

To avoid repeated code we create the PushHelper static class that will have the definition for the message we want to send.

The implementation will be something like:
 

  1. public static class PushHelper    
  2. {    
  3.    /// <summary>    
  4.    /// Gets the windows push message for toast text01.    
  5.    /// </summary>    
  6.    /// <param name="typeOfOperation">The type of operation.</param>    
  7.    /// <param name="content">The content.</param>    
  8.    /// <returns>The IPushMessage.</returns>    
  9.    public static IPushMessage GetWindowsPushMessageForToastText01(string typeOfOperation, string content)    
  10.    {    
  11.        var payload = new XElement("toast",  
  12.                          new XElement("visual",  
  13.                             new XElement("binding",  
  14.                                 new XAttribute("template""ToastText01"),  
  15.                                 new XElement("text",  
  16.                                     new XAttribute("id""1"), message)))).ToString(SaveOptions.DisableFormatting);  
  17.        return new WindowsPushMessage    
  18.        {    
  19.            XmlPayload = payload  
  20.        };    
  21.    }    
  22.   
  23.    /// <summary>    
  24.    /// The get windows push message for toast image and text 03.    
  25.    /// </summary>    
  26.    /// <param name="typeOfOperation">    
  27.    /// The type of operation.    
  28.    /// </param>    
  29.    /// <param name="title">    
  30.    /// The title.    
  31.    /// </param>    
  32.    /// <param name="subtitle">    
  33.    /// The subtitle.    
  34.    /// </param>    
  35.    /// <param name="image">    
  36.    /// The image.    
  37.    /// </param>    
  38.    /// <returns>    
  39.    /// The <see cref="IPushMessage"/>.    
  40.    /// </returns>    
  41.    public static IPushMessage GetWindowsPushMessageForToastImageAndText03(string typeOfOperation, string title, string subtitle, string image)    
  42.    {    
  43.      var payload = new XElement("toast",  
  44.              new XElement("visual",  
  45.                  new XElement("binding",  
  46.                      new XAttribute("template""ToastImageAndText03"),  
  47.                      new XElement("image"new XAttribute("id""1"),   
  48.                                            new XAttribute("src", image),  
  49.                                            new XAttribute("alt""image1")),  
  50.                      new XElement("text"new XAttribute("id""1"), string.Concat(typeOfOperation, " ", title),  
  51.                      new XElement("text"new XAttribute("id""2"), subtitle)  
  52.                      ))).ToString(SaveOptions.DisableFormatting);  
  53.                        
  54.        return new WindowsPushMessage    
  55.        {    
  56.            XmlPayload = payload    
  57.        };    
  58.     }  
  59. }    
 

The typeOfOperation will be “Insert” or “Update” and the content will be the “Title”, ”Subtitle” and “Image” from the object. And the template for Toast notification was used, more specifically the ToastText01 and ToastImageAndText03 but could be another template. See the toast template catalog in this article. The toast template catalog (Windows Runtime apps), the Tile template catalog in this article. The tile template catalog (Windows Runtime apps) and the badge option in this article Badge overview (Windows Runtime apps).

Changing controllers


The controllers BeveragesSchemaController, DessertsSchemaController, MainSchemaController and StartersSchemaController will use the Windows Push Message for ToastImageAndText03 template and the controller SpecialOffersSchemaController will use the Windows Push Message for ToastText01.

Using GetWindowsPushMessageForToastImageAndText03

For example, the complete implementation for the Insert method in the BeveragesSchemaController will be something like:

  1. public async Task<IHttpActionResult> PostBeveragesSchema(BeveragesSchema item)  
  2.        {  
  3.            if (item == null)  
  4.            {  
  5.                throw new ArgumentNullException("item");  
  6.            }  
  7.            if (string.IsNullOrEmpty(item.Title)  
  8.                || string.IsNullOrEmpty(item.Subtitle)  
  9.                || string.IsNullOrEmpty(item.Image)  
  10.                || string.IsNullOrEmpty(item.Description))  
  11.            {  
  12.                return BadRequest("There are properties that are not defined.");  
  13.            }  
  14.            var current = await InsertAsync(item);  
  15.            await Services.Push.SendAsync(PushHelper.GetWindowsPushMessageForToastImageAndText03("Insert:", current.Title, current.Subtitle, current.Image));  
  16.            return CreatedAtRoute("Tables"new { id = current.Id }, current);  
  17.        } 

And the complete implementation for the Update method in the BeveragesSchemaController will be something like:

  1. public async Task<BeveragesSchema> PatchBeveragesSchema(string id, Delta<BeveragesSchema> patch)  
  2.        {  
  3.            if (string.IsNullOrEmpty(id))  
  4.            {  
  5.                throw new ArgumentNullException("id");  
  6.            }  
  7.            if (patch == null)  
  8.            {  
  9.                throw new ArgumentNullException("patch");  
  10.            }  
  11.            var dto = await UpdateAsync(id, patch);  
  12.            await Services.Push.SendAsync(PushHelper.GetWindowsPushMessageForToastImageAndText03("Update:", dto.Title, dto.Subtitle, dto.Image));  
  13.            return dto;  
  14.        } 


Using GetWindowsPushMessageForToastText01

The complete implementation for the Insert method in the SpecialOffersSchemaController will be something like:

  1. public async Task<IHttpActionResult> PostSpecialOffersSchema(SpecialOffersSchema item)  
  2.       {  
  3.           if (item == null)  
  4.           {  
  5.               throw new ArgumentNullException("item");  
  6.           }  
  7.           if (string.IsNullOrEmpty(item.Title)  
  8.               || string.IsNullOrEmpty(item.Subtitle)  
  9.               || string.IsNullOrEmpty(item.Starter1)  
  10.               || string.IsNullOrEmpty(item.Main1)  
  11.               || string.IsNullOrEmpty(item.Dessert1))  
  12.           {  
  13.               return BadRequest("There are properties that are not defined.");  
  14.           }  
  15.           var current = await InsertAsync(item);  
  16.               await Services.Push.SendAsync(PushHelper.GetWindowsPushMessageForToastText01("Insert:", current.Title));  
  17.           return CreatedAtRoute("Tables"new { id = current.Id }, current);  
  18.       } 

And the complete implementation for the Update method in the SpecialOffersSchemaController will be something like:

  1. public async Task<SpecialOffersSchema> PatchSpecialOffersSchema(string id, Delta<SpecialOffersSchema> patch)  
  2.      {  
  3.          if (string.IsNullOrEmpty(id))  
  4.          {  
  5.              throw new ArgumentNullException("id");  
  6.          }  
  7.          if (patch == null)  
  8.          {  
  9.              throw new ArgumentNullException("patch");  
  10.          }  
  11.          var dto = await UpdateAsync(id, patch);  
  12.          await Services.Push.SendAsync(PushHelper.GetWindowsPushMessageForToastText01("Update:", dto.Title));  
  13.          return dto;  
  14.      } 

At the end we should publish the services to the server.

Code

See the source code for the change made in AppStudio.Menu.BackEnd here:

Step 8: Changes the AppStudio.Menu.BackEnd app: add the PushHelper and add support for send notification after an insert or update.

Receive Push Notification

The Menu App will receive the notification, for it the app must be:

  • Associated to the Store
  • Each time the app launch, the app must register the device using the Azure Mobile Service client
  • The Azure Mobile Service should learn the CLIENT SECRET and PACKAGE SID from the Menu App

There are two ways to do it, “automatically” and “manually”. In this article we will use the “automatically” way because it simplifies the process, to see how to define it manually see the article Get started with Push Notifications in Mobile Services.

Push Notification Wizard

Select the Windows 8.1 project and open the context menu, then click in “Add” and then click in “Push Notification…”.



With it we will see a Wizard that will add Push Notification support based on the MyMenuApp Azure Mobile Service and this wizard will inform us about the changes it will do.

Step 1: Before you begin



Step 2: Sign in to the Windows Store



Step 3: Select an app name



In this screen you can reserve an app name if it does not yet exist.

Step 4: Select a service



Step 5: Summary of pending changes



Now the wizard finishes, we will see two separators in Visual Studio, the read me file is:



And the MyMenuAppPush class is:



At this moment, the Menu App for Windows 8.1 supports Push Notification and we should install this version on the device.

The same process should be done for the Menu App for Windows Phone 8.1.

Debugging Push Notifications

Like we mentioned early, Azure Mobile Service is associated with Notification Hubs, for this reason it is possible to test the Menu App, to see if the app is receiving Push Notifications. This test is independent of the implementation in the backend and it wil allow sending a dummy message to see if all is okay.

There are the following two ways to test it:

  • Using Visual Studio
  • Using the Debug from Notification Hubs in Azure Portal

Using Visual Studio

In Visual Studio, open the Server Explorer.



Then expand the Azure item and expand the Notification Hubs item, click in MyMenuAppHub-ns, open the context menu and click in “Diagnose”.



With it, a window in Visual Studio will be opened where it is possible to define the message and the type of the message that we want to send.



In our case the type of the message must be a “Windows (WNS)” and we will choose a Toast.



After this selection the message will be filled using a default message for Toast.

Here is the message we will send:



Pressing the button “Send” we will receive the Toast notification and it is possible to see the message results.



The test Toast notification for Windows Phone 8.1 will be something like:



With this test we can conclude that the Menu App is okay and the registration to receive Push Notification is working.

Using the Debug from Notification Hubs in Azure Portal

Go to the Azure Portal, select MyMenuAppHub-ns Notification Hub. In the Debug separator we will have a similar screen from the Visual Studio, where we can send the messages.

Here is a test sample, like we did in Visual Studio:



After sending the message we will receive the notification and will see the results at the bottom.



Testing real Push Notification using BackOffice

Now we have tested the Menu App to receive notification and the BackEnd was changed, we can use the BackOffice App to change the data and consequently send the Push Notifications.

Insert notification

In the BackOffice app we will insert a new object and we will receive a notification.

Windows 8.1

Using ToastText01 and Insert a Special Offer.



Using ToastImageAndText03 and Insert a Beverage.



Windows Phone 8.1

Using ToastText01 and Insert a Special Offer.



Using ToastImageAndText03 and Insert a Beverage.



Update notification

In the BackOffice app we will update an existing object and we will receive a notification.

Windows 8.1

Using ToastText01 and Update a Special Offer.



Using ToastImageAndText03 and Update a Beverage.



Windows Phone 8.1

Using ToastText01 and Update a Special Offer.



Using ToastImageAndText03 and Update a Beverage.



Using Tags

At this moment, all users will receive notification for all starts, mains, beverages, desserts and special offer. For how they specify that they want to create an option, here the user can subscribe to what they want to receive, tags is the solution.

“Tag expressions enable to target specific sets of devices, or more specifically registrations, when sending a Push Notification through Notification Hubs.”

Suppose that we only want to receive notifications for “starters”, we need:

  • In Menu App: Unregister all notification (if necessary!), using:
    1. await App.MyMenuAppClient.GetPush().UnregisterNativeAsync(); 
  • In Menu App: register the device for the tag “starters”
    1. var tags = new List<string> { "starters" };  
    2. await App.MyMenuAppClient.GetPush().RegisterNativeAsync(channel.Uri, tags); 

  • In the BackEnd: send the message for the specific tag using:
    1. await Services.Push.SendAsync(PushHelper.GetWindowsPushMessageForToastText01("Update:", dto.Title), "starters"); 

To send a message for various languages, we can use tags like “en_starters” or “pt_starters” and in the BackEnd each message will be sent like we saw before, with the difference that the message is in English or in Portuguese, depending on the tag used.

See more about using Tags in Routing and Tag Expressions.

Using Templates

In the BackEnd the PushHelper class was created that uses a specific template, the ToastText01 and it was defined in BackEnd. But it is possible to register the device for a specific template and then the BackEnd can send the template message.

In a Menu App we have these options:



And in BackEnd we will define a TemplatePushMessage to use in the Service.Push.SendAsync method. See more about templates in this article about Templates.