This article is Day #28 in a series called 31 Days of Windows 8. Each of the articles in this series will be published for both HTML5/JS and XAML/C#. You can find additional resources, downloads, and source code on our website.
Today, we are talking about Push Notifications. In the previous 27 days, Clark Sell and I have generally approached each problem the same way, but from a different technology stack. Today, he has followed a pretty traditional development path, where I am going to introduce you to some of the amazing services that are available from Windows Azure. Neither approach is right or wrong, and if you read both articles, you might even find that you like parts of each. With that, let me introduce you to Windows Azure Mobile Services.
There are several steps we’re going to have to take here to get everything set up, so let’s start with setting up a free Windows Azure account at http://www.windowsazure.com.
Click the “try it free” button, and register for an account.
I’m not going to take you through every step of signing up for a free trial account, we’re going to make the leap and assume you can figure it out.
For those of you that are MSDN subscribers, you get Azure for free already! Head over to http://msdn.microsoft.com and click the “Access Benefits” link.
In your Subscription Benefits, you will find access to Windows Store developer account access, Windows Azure access, and several other great benefits. Click the “Activate Windows Azure” link on the Benefits page, and follow the instructions to register.
Now That You Have A Windows Azure Account…
You’ll also need to add Mobile Services to your account (again, it’s free.) Head over to https://account.windowsazure.com/PreviewFeatures to activate the Mobile Services Preview. It looks like this:
You’ll notice that mine has already been activated, but your button will say “try it now” and one click will get the ball rolling.
Now That You Can Use Azure Mobile Services…
Let’s actually create a new mobile service to use with our eventual app. Go to http://manage.windowsazure.com and log in. Click the giant “New +” button at the bottom of the screen:
Make a couple of choices, so that you’re setting up a new Compute > Mobile Services item.
In the first step of the creation process, you need to give your service a name. I’ve named mine “day28-pushnotifications”, and specified that I will use a new SQL database instance. If you’ve already been using Windows Azure before, you can choose one of your existing databases instead.
Next, we need to specify our database settings, like database name, username, and password.
Once you’ve completed these steps, we’ll need to set up our database.
Now That You Have A Database & Mobile Service…
We now need to configure our data source, so that we have a database table to use. Open your mobile service from the Windows Azure Portal, and choose the DATA tab. It should look like this:
Click the “ADD A TABLE” link, and give your table a name. In my case, I’ve named the table Element:
Once you create your table, open it, and click on the COLUMNS tab, like this:
You’ll notice that this table only has an ID column. I just want you to make a note of that…we’ll address it later.
Now That You Have a Database Table Set Up…
We’re finally going to start building our Windows 8 application. You could certainly do this in either order, but I started with Azure just to mix it up. Our next step is to register our application with Windows Live, so that it can take advantage of the Notification Services. (You do not need a Windows Store developer account to do this.) Head over to:
and create a new application in the system, like this:
The name of your app in this system isn’t terribly important, but it should be meaningful so that you remember which is which. Once your new app is created, click on it in the dashboard (like above), and choose “Edit Settings.”
In your settings, choose API Settings, and you will be shown two important values: “client secret” and “Package SID.” Keep these open in a seperate browser tab, or write them down, because you’re going to need them to make this all work.
Now That You Have Your Secret and SID…
It’s probably time to actually start building our actual Windows 8 application. Create a new blank project in Visual Studio 2012, and then right-click on the project name, looking for the “Store” menu option. Click the “Associate app with the Store…” option, and follow along with these screens:
Once you log in with your Windows Live ID, you will see a list of the apps you created earlier, at http://manage.dev.live.com. I’m choosing the Day28 one that I created there.
Finally, click the Associate button, and you’re done. You’ve now associated your Windows 8 app with the app listing on http://manage.dev.live.com.
Now That You’ve Associated Your App With Store…
It’s time to update our Mobile Service, so that it has the credentials necessary to talk with this app via Push Notifications. Jump back to http://manage.windowsazure.com, open your Mobile Service, and choose the PUSH tab, like this:
Take the “client secret” and “package SID” values from earlier, and enter them into these two boxes. I’ve blurred my values out, but you should get the idea. This allows us to then talk directly to the application without any other necessary steps.
Now That Everything Is Finally Configured…
We can return to our application, and actually start writing some code. Since all of this setup actually made it possible to use Azure as our remote database as well, we’ll start there. Open your App.xaml.cs file, where you need to add a few lines of code:
public static MobileServiceClient MobileService =
new MobileServiceClient("https://day28.azure-mobile.net/", "VbUeYTHISISFAKESRRlKSRLqfqXQBmhVqq54");
public static PushNotificationChannel channel { get; private set; }
private async void GetPushChannel()
{
channel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();
}
That first line of code references the name of your service that you created, as well as your “application key.” This can be found by opening your service in the Azure portal, and clicking the “manage keys” button at the bottom of the screen, like this:
And then grabbing your Application Key from this dialog box:
Obviously, I haven’t shown you my keys, but yours should be a jumble of letters and numbers. Finally, you’ll want to call your new GetPushChannel() method from our App.xaml.cs file’s OnNavigatedTo event handler.
Now That You’ve Opened A Push Notification Channel…
We’re nearly home free. To stick with the “elements” theme that many of the articles in this series used, we’ll be storing Element objects in our database that we created earlier. First, I need a new Element class. Mine looks like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
namespace Day28_PushNotifications
{
class Element
{
public int Id { get; set; }
public double AtomicWeight { get; set; }
public int AtomicNumber { get; set; }
public string Symbol { get; set; }
public string Name { get; set; }
public string Category { get; set; }
public string State { get; set; }
[DataMember(Name = "channel")]
public string Channel { get; set; }
}
}
You can see that I have added a bunch of properties, but there’s only two that are really important to our mission in this article: Id and Channel. The ID value is meant to match the Id field we already have in our new database by default, and the Channel value will hold the Channel URI that gets set up when our application executes the code that we added to our App.xaml.cs file earlier.
Now That You’ve Set Up A Custom Class…
One last step before we can write the last bit of code in our project. You need to download the Mobile Services SDK, and install it as part of Visual Studio 2012. Download the Mobile Services SDK by clicking here. I really feel like I should have had you do this earlier, but I couldn’t find a good place to add it in the flow. I’m using lazy loading in my writing as well. We’re adding this so that we have a simple client-side mechanism for communicating with our service.
Now That You’ve Installed the Mobile Services SDK…
To keep it simple, I’ll just tell you that I’ve added a simple Button control to my MainPage.xaml file, and added a click event to it that calls AddElementButton_Click(). I’ve also needed to add a new reference to my project that was a part of the Mobile Services SDK.
Right-click on your References folder in your project, and choose “Add Reference…”
In the window that opens, choose the Windows Azure Mobile Services Managed Client, and click OK. This will add the reference to your project, and allow us to add a new using statement to our MainPage.xaml.cs file:
using Microsoft.WindowsAzure.MobileServices;
By adding this namespace, we’re able to interact directly with our data tables in Windows Azure. To make a simple insert into the Element table that we created so long ago, here is the syntax we can use:
Element element = new Element { AtomicNumber = 1,
AtomicWeight = 1.01,
Category = "Alkali Metals",
Name = "Hydrogen",
Symbol = "H",
State = "Gas",
Channel = App.channel.Uri };
await App.MobileService.GetTable<Element>().InsertAsync(element);
As you can see, it takes two lines of code to make an insert into our database. In fact, if you open your Windows Azure Portal to your Mobile Service’s DATA tab, you can see the records appear dynamically. Here’s a quick video to illustrate that:
So at this point, we now have a very simple application that inserts data into our Azure database. But wasn’t this article about Push Notifications? Where are we headed? Before we get there, here’s the entirety of my MainPage.xaml.cs file, so you can see exactly what’s happening in the code in the video:
using System.Collections.Generic;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
namespace Day28_PushNotifications
{
public sealed partial class MainPage : Page
{
int counter = 0;
List<Element> elements;
public MainPage()
{
this.InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
CreateElementList();
}
private async void AddElementButton_Click(object sender, RoutedEventArgs e)
{
Element element = elements[counter];
element.Channel = App.channel.Uri;
await App.MobileService.GetTable<Element>().InsertAsync(element);
counter++;
if (counter >= elements.Count)
counter = 0;
}
private void CreateElementList()
{
elements = new List<Element>();
elements.Add(new Element { AtomicNumber = 1, AtomicWeight = 1.01, Category = "Alkali Metals", Name = "Hydrogen", Symbol = "H", State = "Gas" });
elements.Add(new Element { AtomicNumber = 2, AtomicWeight = 4.003, Category = "Noble Gases", Name = "Helium", Symbol = "He", State = "Gas" });
elements.Add(new Element { AtomicNumber = 3, AtomicWeight = 6.94, Category = "Alkali Metals", Name = "Lithium", Symbol = "Li", State = "Solid" });
elements.Add(new Element { AtomicNumber = 4, AtomicWeight = 9.01, Category = "Alkaline Earth Metals", Name = "Beryllium", Symbol = "Be", State = "Solid" });
elements.Add(new Element { AtomicNumber = 5, AtomicWeight = 10.81, Category = "Non Metals", Name = "Boron", Symbol = "B", State = "Solid" });
elements.Add(new Element { AtomicNumber = 6, AtomicWeight = 12.01, Category = "Non Metals", Name = "Carbon", Symbol = "C", State = "Solid" });
elements.Add(new Element { AtomicNumber = 7, AtomicWeight = 14.01, Category = "Non Metals", Name = "Nitrogen", Symbol = "N", State = "Gas" });
elements.Add(new Element { AtomicNumber = 8, AtomicWeight = 15.999, Category = "Non Metals", Name = "Oxygen", Symbol = "O", State = "Gas" });
elements.Add(new Element { AtomicNumber = 9, AtomicWeight = 18.998, Category = "Non Metals", Name = "Fluorine", Symbol = "F", State = "Gas" });
elements.Add(new Element { AtomicNumber = 10, AtomicWeight = 20.18, Category = "Noble Gases", Name = "Neon", Symbol = "Ne", State = "Gas" });
elements.Add(new Element { AtomicNumber = 11, AtomicWeight = 22.99, Category = "Alkali Metals", Name = "Sodium", Symbol = "Na", State = "Solid" });
elements.Add(new Element { AtomicNumber = 12, AtomicWeight = 24.31, Category = "Alkaline Earth Metals", Name = "Magnesium", Symbol = "Mg", State = "Solid" });
elements.Add(new Element { AtomicNumber = 13, AtomicWeight = 26.98, Category = "Other Metals", Name = "Aluminum", Symbol = "Al", State = "Solid" });
elements.Add(new Element { AtomicNumber = 14, AtomicWeight = 28.09, Category = "Non Metals", Name = "Silicon", Symbol = "Si", State = "Solid" });
elements.Add(new Element { AtomicNumber = 15, AtomicWeight = 30.97, Category = "Non Metals", Name = "Phosphorus", Symbol = "P", State = "Solid" });
elements.Add(new Element { AtomicNumber = 16, AtomicWeight = 32.06, Category = "Non Metals", Name = "Sulfur", Symbol = "S", State = "Solid" });
elements.Add(new Element { AtomicNumber = 17, AtomicWeight = 35.45, Category = "Non Metals", Name = "Chlorine", Symbol = "Cl", State = "Gas" });
elements.Add(new Element { AtomicNumber = 18, AtomicWeight = 39.95, Category = "Noble Gases", Name = "Argon", Symbol = "Ar", State = "Gas" });
elements.Add(new Element { AtomicNumber = 19, AtomicWeight = 39.10, Category = "Alkali Metals", Name = "Potassium", Symbol = "K", State = "Solid" });
elements.Add(new Element { AtomicNumber = 20, AtomicWeight = 40.08, Category = "Alkaline Earth Metals", Name = "Calcium", Symbol = "Ca", State = "Solid" });
elements.Add(new Element { AtomicNumber = 21, AtomicWeight = 44.96, Category = "Transitional Metals", Name = "Scandium", Symbol = "Sc", State = "Solid" });
elements.Add(new Element { AtomicNumber = 22, AtomicWeight = 47.90, Category = "Transitional Metals", Name = "Titanium", Symbol = "Ti", State = "Solid" });
elements.Add(new Element { AtomicNumber = 23, AtomicWeight = 50.94, Category = "Transitional Metals", Name = "Vanadium", Symbol = "V", State = "Solid" });
elements.Add(new Element { AtomicNumber = 24, AtomicWeight = 51.996, Category = "Transitional Metals", Name = "Chromium", Symbol = "Cr", State = "Solid" });
elements.Add(new Element { AtomicNumber = 25, AtomicWeight = 54.94, Category = "Transitional Metals", Name = "Manganese", Symbol = "Mn", State = "Solid" });
elements.Add(new Element { AtomicNumber = 26, AtomicWeight = 55.85, Category = "Transitional Metals", Name = "Iron", Symbol = "Fe", State = "Solid" });
elements.Add(new Element { AtomicNumber = 27, AtomicWeight = 58.93, Category = "Transitional Metals", Name = "Cobalt", Symbol = "Co", State = "Solid" });
elements.Add(new Element { AtomicNumber = 28, AtomicWeight = 58.70, Category = "Transitional Metals", Name = "Nickel", Symbol = "Ni", State = "Solid" });
elements.Add(new Element { AtomicNumber = 29, AtomicWeight = 63.55, Category = "Transitional Metals", Name = "Copper", Symbol = "Cu", State = "Solid" });
elements.Add(new Element { AtomicNumber = 30, AtomicWeight = 65.37, Category = "Transitional Metals", Name = "Zinc", Symbol = "Zn", State = "Solid" });
elements.Add(new Element { AtomicNumber = 31, AtomicWeight = 69.72, Category = "Other Metals", Name = "Gallium", Symbol = "Ga", State = "Solid" });
elements.Add(new Element { AtomicNumber = 32, AtomicWeight = 72.59, Category = "Other Metals", Name = "Germanium", Symbol = "Ge", State = "Solid" });
elements.Add(new Element { AtomicNumber = 33, AtomicWeight = 74.92, Category = "Non Metals", Name = "Arsenic", Symbol = "As", State = "Solid" });
elements.Add(new Element { AtomicNumber = 34, AtomicWeight = 78.96, Category = "Non Metals", Name = "Selenium", Symbol = "Se", State = "Solid" });
elements.Add(new Element { AtomicNumber = 35, AtomicWeight = 79.90, Category = "Non Metals", Name = "Bromine", Symbol = "Br", State = "Liquid" });
elements.Add(new Element { AtomicNumber = 36, AtomicWeight = 83.80, Category = "Noble Gases", Name = "Krypton", Symbol = "Kr", State = "Gas" });
}
}
}
Now That You Have Database Transactions…
We can test out the old Push Notifications. For this example, we are going to send a toast notification that shows the name of the element we inserted. There are millions of ways we could handle this, but ultimately, we’re building something that is triggered by a database transaction, which is likely how you are going to build your push notifications as well.
Remember, push notifications will come from our service, not from our app, so we’re headed back to the Windows Azure Portal at http://manage.windowsazure.com. Open your mobile service, click the DATA tab, and then choose your data table, which in my example is named Element. When you are viewing the table, flip over to the SCRIPT tab, where you will see something like this:
By default, you’ll be looking at the INSERT script for our database. This JavaScript code will be executed every time a record is sent to the database. We are going to modify this script (yes, I know it’s JavaScript, but it’s our only option.) If you click the ? button in the bottom right corner, there are some excellent tutorials on doing different kinds of transactions, like:
Anyways, I’ve modified my INSERT script to determine if my record was successfully inserted, and if it was, to send a push notification to the channel that was stored with that record.
function insert(item, user, request) {
request.execute({
success: function() {
request.respond();
push.wns.sendToastText02(item.channel, {
text1: "(" + item.AtomicNumber + ") " + item.Name + " - " + item.Category,
text2: item.Symbol + " | " + item.AtomicWeight + " | " + item.State + " | "
}, {
success: function(pushResponse) {
console.log("PUSH sent:", pushResponse);
}
});
}
});
}
If you will recall back to Day #10, when we worked on Toast Notifications, there were several different Toast templates that we could use. This code uses those exact same templates. In this example, I’m using ToastText02. I set the text values of Text1 and Text2, and then write a success statement to my log file.
Updating this script is ultimately what sends your toast messages for you, and you can get as elaborate as you’d like. For example, perhaps you save all of the “channels” that are sent to your database in one table, and then when your data changes (let’s say you’re a weather app, and you just got a new record indicating a blizzard is on the way) you could create a loop that would send a notification to every channel that is affected, based on other data in your database.
In short, the sky’s the limit.
Now That You’re Sending Push Notifications…
One last thing. Remember how we had to update our package.appxmanifest file to allow toast messages on Day #10? That still applies here. Open your file, and choose “Yes” to make your app Toast Capable. Without this, you’ll never see the beautiful toast messages that are being sent to your machine.
Once you’ve made that change, every time you click the button in your application, you’ll not only be inserting a record into your Azure database, but you’ll also be sending back a Toast Notification to the user’s machine. Amazing.
Summary
Today, we took a look at Push Notifications by way of Windows Azure Mobile Services. If you’re building an app that is going to have online data storage, push notifications, and even potentially multiple clients, like iOS, Android, or others, this will become an invaluable tool for you. As I took this process apart, I was absolutely amazed at how easy everything was, and how integrated the experience is for us as developers.
If you would like to download my sample application that uses the code from this article, click the icon below:
Tomorrow, we’re going to look at the lifecycle of an app, and the many ways that a user can open, as well as return to, your app. See you then!
Leave a Reply