Share via


Windows 8 Notifications: Push Notifications

Previous Notification Posts

Overview

Programmatic Concepts

Image Handling

Leveraging Azure Storage

Local Notifications

Scheduled Notifications

Periodic Notifications

Using Azure for Periodic Notifications

It’s been a while since my last post on the topic of notifications in Windows 8, so I’m going to pick things back up and cover the two remaining notification options: push notifications and raw notifications. If you’re new to my blog (or even it not), there’s a link list to the right so you can catch up on the other posts.

Personalizing the User Experience

Push notifications are one of the hallmarks of a personalized application experience. The primary difference from the other notification mechanisms discussed so far is that the application itself does not set the delivery schedule. In the push notification scenario, a Windows 8 application is merely a subscriber to a hosted service that is responsible for triggering the notification and sending it to interested parties.

Think of a weather application that alerts you to severe storms in the area or a retail application that informs you when an item you are tracking is on sale. A chat application is another prototypical example; we’re all accustomed to seeing a toast message when a friend wants to get hold of us. In all of these scenarios, a “third-party’ owns the notification context; they decide what is important to send out and when.

How it works

There’s a bit of plumbing involved in push notifications, but the good news is that most of that plumbing is maintained and managed for you.

As you can see from the image below, there are four primary actors, two for which you are wholly responsible and two that are provided by Microsoft as part of the platform:

  • Windows Store App: is, of course, your awesome Windows 8 application
  • Cloud Service: is a service that you build (or tap into) that is responsible for two things
    • keeping track of the devices/users that are running your app
    • generating content that will be pushed to a subset (typically) of those users via a tile or toast notification.
  • Windows Notification Service (WNS): is a Microsoft-provided cloud service that is responsible for sending out the notification to the targeted clients
  • Notification Client Platform (NCP): is a subset of the Windows 8 OS that interacts with WNS and passes the relevant notifications to the app running on the given device.

The other primary element of this workflow is something known as a notification channel, which is a unique URI that identifies a single user on a single device for a single application (or secondary tile).

Push Notification workflow

Here's a closer look at each step of the workflow:

Step Initiator Responder Action
1 Your application Notification Client Platform (NCP) Your application requests a notification channel (via CreatePushNotificationChannelForApplicationAsync)
2 NCP Windows Notification Service (WNS) A notification channel URI is returned from WNS; that URI uniquely identifies the application, user, and device from which the request was made
3 NCP Your application The notification channel is returned as a URI in the notify.windows.com domain.
4 Your application Cloud Service The notification channel URI along with any other information about the client that the service will use to determine when to send a notification is passed to the service and stored for future use. The API for this invocation is completely up to the developer of the application and service.
5 Cloud Service WNS In response to an interesting external event, the Cloud Service initiates the push of information to a subset of the clients that have registered for such notifications. The request occurs over a SSL connection using the OAuth 2.0 protocol.
6 WNS NCP The tile or toast notification is transmitted to the appropriate client machines (and applications) and made manifest.

As you can see, Steps 1 and 4 are the only two you have to write any code for, and Step 1 is little more than one API call!

The Cloud Service is as involved and complex as you want it to be, but in terms of the workflow is a black box. As long as it manages the OAuth exchange and provides a tile or toast template to WNS, all is well. I’ll take a deeper dive into Steps 4 and 5 in my next blog post, leveraging Windows Azure Web Sites to host the service.

Design Considerations for Push Notifications

A well executed push notification strategy can make your application become a vital part of your users’ digital experience, encouraging frequent visits to your app. Conversely, a poor execution may have the effect of a car alarm (who pays attention to those any more?) or, worse, result in the user uninstalling your application. While each application’s scenario and user base will have its unique characteristics, there are some common themes to consider when formulating what that experience will be in your app.

Can You See Me Now?

Never, ever assume your user will see a given notification. There are numerous ways that a user may disable notifications or otherwise not receive notifications from your application:

  • Settings flyoutA user can turn off notifications via the PC Setting option accessible via the Settings charm; she may elect to do this for all applications or on an app-by-app basis.
  • Notifications can be turned off temporarily – “quiet time” – via the notifications icon on the Settings panel (see right).
  • Applications with notifications typically expose the option to turn notifications off in the application-specific Settings flyout.
  • A toast notification that’s initiated while the user is off-line will not be delivered. A tile or badge notification will be cached, but only the latest is retained for delivery unless the notification queue is enabled (in which case up to five notifications can be cached).
  • The notification channel can expire (as of this writing after 30 days), and notifications delivered to a inactive channel will be dropped. A best practice is to renew the notification channel for your application each time it is launched and then refresh the directory of channels maintained by your Cloud Service as necessary. If the application might not be launched for extended periods of time, consider using a maintenance trigger to refresh the channel. Consult the Push and periodic notifications client-side sample for code that implements a maintenance task for this purpose.

Delight. Don’t Annoy.

There is no magic sauce here, and the ‘formula’ differs based on the type of application and the expectation of the users; nevertheless, there are a few things to keep in mind.

  • Specific and context-sensitive notifications should be delivered as soon as possible, but do remember there is no guarantee they will be seen by the user. There is no directory of undelivered notifications that you can consult, so if there is information you want the user to see, consider backing up that notification with application functionality that will display potentially missed – but still relevant – notifications to the user when they do revisit your application.
  • Generic content that’s more broadly delivered, like a stock quote or weather update, should be sent with a cadence of no more than once every 30 minutes. More frequent delivery runs the risk of both annoying the users and having the requests throttled by WNS.
  • Consider the context of the application when the notification is received to determine if that notification should occur. A prime example is a toast notification received while the application is in the foreground. In most cases, you’ll want to suppress the notification and just incorporate the content of the notification within the UI as a matter of course. For instance, I don’t want to see notifications of e-mails arriving when I’m in my mail application and can clearly see them appear in my in-box. If you decide a notification should not be presented to the user, your code can cancel that notification via an event handler for PushNotificationReceived.

Be Careful Out There!

First and foremost, don’t transmit sensitive information like passwords or bank account numbers. Beyond that though, note there are at least two publically accessible services involved in the delivery of push notifications: your Cloud Service and WNS.

The connection between your Cloud Service and WNS must be over SSL and is secured via the OAuth 2.0 protocol. The Cloud Service maintains – and must secure – the application’s package security identifier (SID) and client secret. That information is sent to WNS to obtain an OAuth token to make requests to WNS, so if the SID and client secret are compromised a malicious service could initiate push notification to your application’s users.

The connection between your application and the Cloud Service is completely at your discretion. Over that connection will pass the notification channel URIs of your users’ devices along with additional metadata or profile information your service uses to determine which users should receive which notifications. Given the potential sensitivity of that information, it’s also recommended this connection be secured by SSL.

Additionally, you’ll want to ensure the persistent storage location that your Cloud Service uses for the client notification channel URIs and other information is also secure and perhaps encrypted. Each of the notification channel URIs should be validated as targeting the notify.windows.com domain before being acted upon. If your storage is compromised, and a rogue party surreptitiously substitutes an alternative server endpoint, you could unknowingly divulge your application package SID and client secret.

Course Correct.

Consider using HTTP headers and response codes from the exchange with WNS to get a somewhat rough idea of the effectiveness of your notification strategy.

Push notification requests can include an optional HTTP header, X-WNS-RequestForStatus , which, when set to true, causes WNS to include an X-WNS-DeviceConnectionStatus header in the HTTP response with one of three values:

  • connected: the device is online and connected to WNS.
  • disconnected: the device is offline and not connected to WNS.
  • tempconnected: the device temporarily lost connection to WNS (e.g., a 3G connection was lost, or the user turned off the wireless hardware switch on a laptop).

The X-WNS-NotificationStatus response header also has one of three values providing some insight into the disposition of the notification.

  • received: the notification was received and processed by WNS.
  • dropped: the notification was explicitly dropped because of an error or because the client has explicitly rejected these notifications. Toast notifications will also be dropped if the device is offline.
  • channelthrottled: the notification was dropped because the app server exceeded the rate limit for this specific channel.

With X-WNS-DeviceConnectionStatus you may be able to better target when you are sending your notifications by building a profile of the number of connected users at different times of the day.  X-WNS-NotificationStatus can’t tell you how many are receiving the notification, but it can give you a lower bound on how many are being rejected (dropped).

Of course, there’s the HTTP status code of the request to WNS itself, several of which can give some insight into your user base. A 410, for instance, indicates the notification channel is no longer valid, which may mean a user hasn’t run the app recently (or you need to reassess how you are refreshing your client notification channels in code).

Comments

  • Anonymous
    October 16, 2012
    Hi O'Neil Good article. Here I have one question, Can I use my own hosted web service(Which is On-Premise) instead of cloud service..? Any help from your side, really appreciated. Thanks Karthik Vadla

  • Anonymous
    October 18, 2012
    Karthik, You can host the "Cloud Service" in the workflow above pretty much wherever you like as long as it's accessible from the Windows 8 clients. The WNS is managed my Microsoft though so whatever (and wherever) your service is, it must communicate with WNS.

  • Anonymous
    June 25, 2013
    Hi O'Neil I have a question.When my app was closed,I pushed a tile via the cloud server,and my app recived the tile.Then I opened my app,how can I catch the main id showing on the tile?If I know the main id,I can show the detail content about the info on the tile.What is your opinion?

  • Anonymous
    June 27, 2013
    Mr. Sophia,  when a notification is sent, it can include "launch" arguments that can be accessed when the application is launched via the tile.  In that code you can take specific action to redirect (deep link, etc.) to the desired content.

  • Anonymous
    July 01, 2013
    Hi O'Neil Thank for your reply. And I have another question about the BackgroundTask.In my app ,I register the background task according to the sample supplied by Microsoft.For conveninence, I set the Time Zone Changed as the trigger.Then I run my app step by step along with the breakpoints, change the Time Zone ,my app can not step into the BackgroundTask method ,even the run method, but exit completely. To begin , I think there is already one background task which name is same to my app backgroud task,then I try to change the task name、the task entrypoint and the task method.But I get the same error result. Perhaps there are still some important points in the backgroud task that I ignored. Could you ,O'Neil,explain why my app exit instead of step  into the backgroud task method? And the code ,please check the below social msdn link social.msdn.microsoft.com/.../trigger Thank you very much

  • Anonymous
    August 29, 2013
    Any idea about the expiration time of the OAuth token (obtained from WNS)?

  • Anonymous
    August 30, 2013
    iuliub, I haven't seen anything published on the token expirations and it somewhat stands to reason that we wouldn't want to publicize, partially for security reasons and mainly to give us leeway to change it without the risk of developers relying on a specific value.  In the documentation here: msdn.microsoft.com/.../hh913756.aspx there's guidance about checking the return from a notification request, and if you've found the token has expired, request a new one. The best bet is to incorporate that pattern into your implementation and then the answer to your original question doesn't really matter for a practical perspective.