Windows 8.1 Store Apps, Azure Mobile Services & Notification Hubs

NB: Fairly rough notes of a couple of changes (particularly around Notification Hubs) I came across while working in Visual Studio 2013 Update 2 RC today. Take with a small pinch of salt and always consult http://www.windowsazure.com/mobile for definitive.

Ok, I’ll admit that from time to time I get a little behind the times but I noticed some changes today in the way things are working between Visual Studio (2013 Update 2 RC) and Azure Mobile Services so I thought I’d try and write them up as I demonstrated some of this functionality just last week and it looks like there have been updates.

Let’s say that I create a blank Windows Store 8.1 app;

image

and then imagine that I want to create an Azure Mobile Service for this app from the Server Explorer;

image

and I go ahead and fill in the various details;

image

and I create that service and then I create a table;

image

and I enter some details in there;

image

and get that created and then let’s say I want to write some code against that table so I use Visual Studio’s little “Add Connected Service…” dialog;

image

and that lets me pick the service in question;

image

and that does some work for me such as;

  1. Adding a reference to various libraries.
  2. Adding a definition of a proxy class (i.e. a MobileServiceClient) to my App.xaml.cs file.

with that code looking like;

image

and then I have a slight problem because I’ve configured my table to only allow for authenticated access so I could (e.g.) maybe add some UI to invoke a piece of code that causes a login;

image

and I could go and visit Google’s Developers Console (https://console.developers.google.com/project) and set up a new project like this one;

image

and then I can create a new client ID and secret for this project;

image

and copy them back into the Azure Mobile Services portal in the right section;

image

and exercise my code to login to the application via Google;

image

and that’s all good and I’m logged in and I could now write code to run and insert a record into my table such as;

image

and that all works quite nicely. Now, if I did (purely for an example) want to add some custom API that allowed a caller to get the data from this table then I can now do this via Visual Studio which is a new thing;

image

and that pops a dialog for me;

image

NB: this is just for an example and then I can edit the script in Visual Studio;

image

adding something like;

image

and then I can invoke that from (e.g.) PowerShell;

image

and that all works nicely and I’ve got a custom API created entirely in Visual Studio without visiting the Azure Mobile Services portal.

The next (big) change that I came across was the way in which notification hubs are brought into Azure Mobile Services for push notifications. I noticed when I created my service a new entry in the Server Explorer;

image

and I can see some properties on this in Visual Studio;

image

I’m not particularly well versed in Notification Hubs so I thought I’d engage in a bit of background reading;

Now, this isn’t new but it’s new to me as a Mobile Service user as I have tended to just manually do push myself previously even though hubs were available. What they seem to offer to me is;

  1. Scale – for broadcast/non-broadcast delivery.
  2. Abstraction of the differences between PNS systems.
  3. Management of PNS registration details.

I also wondered how this worked for free/paid Mobile Service usage and so had a look at the “Scale” option for my hub which was running in the “free” tier;

image

and that leads on to the page over here which lists the way that the pricing works.

Looking at the Azure Portal, I see a few things;

image

What I notice as “different” here is if I use the portal to create a new mobile service then this tab displays something different – by default creating a service this way doesn’t currently seem to switch on notification hubs,

image

and so there’s a different UI and that little button at the bottom, middle of the screen which presumably turns on hubs.

Where I noticed this first was in using the dialog that Visual Studio gives you for adding “push notifications” into a project. That dialog is still there;

image

and what it used to do for me was something like this;

  1. Add libraries into the project if they weren’t already there.
  2. Add a declaration of a proxy onto my App class (of type MobileServiceClient).
  3. Sets up the right bits at the Windows Store such that my app is able to use the WNS service.
  4. Add a new table called channels into my Mobile Service.
  5. Add a modified insert script to that table such that it did some work to attempt to de-duplicate any doubly registered channel URIs.
  6. Added code to my client side project to get hold of a unique installation ID and to post it to the channels table in the cloud along with the primary URI for notifications for my app for the user on this device.
  7. Sets my app manifest up to allow toast notifications.

With the integration of notification hubs, it doesn’t seem to do that any more by default for a new project like the one I’ve created in this post in Visual Studio 2013 Update 2 RC.

The dialogs involved are the same as before – i.e. you need to associate your app with a Store package if you haven’t already;

image

and then you select a mobile service;

image

What seems to happen now is something like;

  1. Add libraries into the project if they weren’t already there.
  2. Add a declaration of a proxy onto my App class (of type MobileServiceClient).
  3. Sets up the right bits at the Windows Store such that your app is able to use the WNS service.
  4. Configures the notification hub to be able to deliver via the WNS service.
  5. Writes some code in order to register my app’s channel with this hub for this user on this device.
  6. Writes some more code (in my App.OnLaunched override) to call the code that it wrote in Step (5) when the app starts up – I wasn’t too keen on this as I’d perhaps want this code elsewhere.
  7. Writes a new custom API called notifyallusers.js.

I can see (4) in both Visual Studio;

image

and in the portal display for my hub;

image

The code written in (5) looks like this and goes (as before) into a file called push.register.cs within a services sub-folder of the project;

  internal class mtaultyVampireHunterPush
  {
    public async static void UploadChannel()
    {
      var channel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();

      try
      {
        await App.proxy.GetPush().RegisterNativeAsync(channel.Uri);

        // You would perhaps want to take this out 🙂
        await App.proxy.InvokeApiAsync("notifyAllUsers");
      }
      catch (Exception exception)
      {
        HandleRegisterException(exception);
      }
    }

    private static void HandleRegisterException(Exception exception)
    {

    }
  }

and it’s not entirely transparent what this code is doing but it’s clear that it’s getting (in this case) the application’s primary URI for notifications and is registering it with the cloud (the notification hub) and then the line of code making the call to InvokeApiAsync tries to immediately call the notifyAllUsers custom API that the dialog has just created so I removed that code pretty quickly.

That custom API script looks something like this;

// See documentation at http://go.microsoft.com/fwlink/?LinkId=296704&clcid=0x409
exports.post = function(request, response) {
    response.send(statusCodes.OK,{ message : 'Hello World!' })
    
    // The following call is for illustration purpose only
    // The call and function body should be moved to a script in your app
    // where you want to send a notification
    sendNotifications(request);
};

// The following code should be moved to appropriate script in your app where notification is sent
function sendNotifications(request) {
    var payload = '<?xml version="1.0" encoding="utf-8"?><toast><visual><binding template="ToastText01">' +
        '<text id="1">Sample Toast</text></binding></visual></toast>';
    var push = request.service.push; 
    push.wns.send(null,
        payload,
        'wns/toast', {
            success: function (pushResponse) {
                console.log("Sent push:", pushResponse);
            }
        });
}

and what that’s doing is broadcasting a toast notification out to any channel that’s registered with the notification hub. What I found most interesting about this code is that it’s still using the push.wns.send method and that this seems to somehow have been rewired to use notification hubs rather than the previous mechanism which was (AFAIK) a direct communication with WNS (or MPNS etc.). Now, there is a bit in the docs which says;

“This operation resets your push credentials and changes the behavior of the push methods in your scripts”

which might be pointing to push.wns.send doing different things once a notification hub is in set up for the Mobile Service but I’ve not checked that out fully at the time of writing and that document that I pointed to doesn’t walk through doing this stuff via the dialog in Visual Studio, it seems to take a more manual route.

With all that in place though, I can put some UI (like a button) on the screen to invoke the code that’s been written for me (taking out the C# code above which tried to call NotifyAllUsers once the channel URI had been registered);

image

The first thing I noticed when I ran this code (without logging in) was that I got back an “unauthorized” exception back from the call to RegisterNativeAsync() listed previously.

I spent a bit of time on this, performing one of those “binary chop” style exercises on my own code versus a blank project until I realised that my code was constructing the MobileServiceClient proxy without an application key whereas the blank project was using the application key.

Based on that, I guess that access to the notification hub (i.e. the ability to register with the notification hub) is being controlled by passing the application key to the service. I’m not sure if that’s the only option (unlike a table or a custom API which allows other options) but that’s the only option that I’ve tried to make use of for the moment.

So, I changed my code to pass the application key when it constructed the MobileServiceClient instance and I seemed to be able to register with the hub. The portal showed me;

image

I’d actually expected this to show up in a different area but it was definitely a sign of life Smile

With that registration in place, I could debug my push notifications from the hub either from Visual Studio or from the portal which I thought was pretty cool. That is;

image

pops up a Visual Studio page;

image

which I can use to send the app a toast;

image

which is quite cool Smile

Having learnt how to broadcast, I wondered how I would direct a notification to a particular user. I read a little more around tags and (in the first instance) played around with the registration code so add the current user id as a tag;

image

and then tested that out from the debugging tool in Visual Studio and the notifications seemed to reach that user just fine.

Conversely, changing the tag slightly caused notifications to not show up.

I’m not at all sure at the time of writing whether that’s a reasonable thing to do so I’ll update the post if I find out that it’s not.

That’s it for this post – as I said at the start, these are rough notes in coming to the changes here in Mobile Services for the first time so posted here purely as a way of trying to be helpful if you’re grappling with similar things. There are docs on the main site but I found that they didn’t quite walk through the same path that I was trying to follow here and hence the post.