Creating a Great Mashup Part 3

This post details features used by Earthquake Explorer, a Windows 8 app that displays earthquake information on Bing maps.   Earthquake Explorer was based off of the Earthquakes mashup starter kit on github.  Read part 1 here.  Read part 2 here.  We left off Part 2 talking about creating a compelling live tile in Windows 8.   This really is a must-do feature in Windows 8 – primarily because a live tile creates a more compelling app experience.  It encourages the user to keep the live tile ‘pinned-left’ (that is, more likely on their primary screen), and encourages the user to open the app more frequently.  That equals higher app usage, higher ad impressions, etc.  Because the earthquake app is consuming earthquake data on our backend using Windows Azure Mobile Services, it’s trivial to send notifications when new earthquakes are detected.  We can send a nice live tile that looks like so: Clearly, this is better than displaying _nothing_, and the map adds a professional look to it.   We can also combine this with badges – for example, in Dark Skies, I do something similar when users add new locations to the map, adding a badge notification that displays how many new locations are nearby: The first step in doing this is to determine which tile template to use.  Because the map is the main image, this is a pretty simple as we’d want the map to take up the main tile.  The place to look is the tile template catalog on MSDN.  In this case, TileWideImageAndText02 seems to fit the bill for wide tiles, and TileSquareImage is the bet bet for smaller, square-sized tiles.  From the template page: The key here is the tile XML – it’s the same if we’re doing a push notification, if the app is updating its own tile, or if Windows is updating the tile using the TileUpdater using periodic updates.  To get the image, we’ll use the Bing Maps REST API, which requires a valid Bing Maps key from the portal site.  For a wide tile, we can get a static map using a URL like so, specifying the zoom level (2), centered location (36 latitude, –79 longitude), pushpin location (also at 36 latitude, –79 longitude), and a size of 310x100: http://dev.virtualearth.net/REST/v1/Imagery/Map/Road/36,-79/2?mapSize=310,100&pushpin=36,-79;48&key={your_api_key} Which returns an image like so: From the Windows Azure Mobile Service, it’s fairly simple to send a notification with some code like the below.  I’m removing some of the dynamic text to shorten it up a little, but realistically we’d be setting the location of the pin(s) and text of the tile itself dynamically: 1: function sendNotification(channelUri) { 2:   3: var baseImageUrl = "http://dev.virtualearth.net/" + 4: "REST/v1/Imagery/Map/Road/36,-79/2?[mapsize]" + 5: "&pushpin=36,-79;48&key={your_api_key}"; 6: 7: var smallImage = baseImageUrl.replace("[mapsize]", "mapSize=150,150"); 8: var bigImage = baseImageUrl.replace("[mapsize]", "mapSize=310,100"); 9:   10: var payload = "<tile><visual><binding template='TileWideImageAndText02'>" + 11: "<image id='1' src='" + xmlEscape(bigImage) + "' alt='map'/>" + 12: "<text id='1'>Some top line text here</text>" + 13: "<text id='2'>Some bottom line text here</text>" + 14: "</binding>" + 15: "<binding template='TileSquareImage' branding='none'>" + 16: "<image id='1' src='" + xmlEscape(smallImage) + 17: "' alt='map'/></binding></visual></tile>"; 18:   19: var theTag = 'some_identifier'; 20: push.wns.send(channelUri, payload, 'wns/tile', 21: { 22: client_id: 'your ms-app:// id', 23: client_secret: 'your client secret', 24: headers: { 'X-WNS-Tag': theTag } 25: }, 26: function (error, result) { 27: if (error) { 28: console.log("(" + error.statusCode + ") Error sending notification"); 29: } 30: } 31: ); 32: }  .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } (Note: the xmlEscape method is omitted, but is a simple method that escapes special characters for the XML document.)  What we’re doing here is using the push.wns (Windows Notification Service) object to send the tile XML directly.   If you review the script reference, it is certainly simpler to use the push.wns.sendTileWideImageAndText02 method, but I generally prefer to build the XML directly as done above.  The reason is that it allows you to bundle multiple notifications together – such as including both the wide and narrow tile versions.  (The other side benefit is that this allows you to enter the application package ID and secret, which should allow a single WAMS to send notifications to multiple applications.) We’ll look at other mashup examples in future posts!

Creating a Great Mashup Part 2

This post details features used by Earthquake Explorer, a Windows 8 app that displays earthquake information on Bing maps.   Earthquake Explorer was based off of the Earthquakes mashup starter kit on github.  Read part 1 here.  In the first part, we created a Windows Azure Mobile Service to store data as a back end for our mashup.  A big benefit of this approach is that it lets us filter/sort/query the data any way we’d like, and our application is now resilient against outages and changes in the schema.   In this part, we are going to modify our existing scheduled task to consume the actual USGS data feed and store it in a table. Getting the data is simple, thanks to the nice GeoJSON feed provided by the USGS.  Read more about that here: http://earthquake.usgs.gov/earthquakes/feed/v1.0/ From within our scheduled job, we can query it like so: function fetchUSGS() { console.log('Starting job'); var httpRequest = require('request'); var uri = 'http://earthquake.usgs.gov/earthquakes/feed/v0.1/summary/all_hour.geojson'; httpRequest(uri, function (err, response, body) { if (err) { console.warn('Error connecting to service.'); } else if (response.statusCode !== 200) { console.warn('Unexpected reply.'); } else { //got reply, process the results var theData = JSON.parse(response.body); processData(theData); } }); } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } We’re making a request to the feed (uri) and specifying the callback as the inline function.   There really isn’t any robust error handling, but then, there really isn’t much you can do in the event of an error except just try again the next time the task runs.  Calling JSON.parse() will, naturally, parse the response text into a nice object collection we can parse.  If we look at the JSON in fiddler, you can see the structure of the document: The JSON contains a collection of features, where each feature contains a geometry object, an id string, and a properties object.  Either through the documentation on the USGS site, or through examining the results, we’ll need to know the structure of the data. To make working with the data a bit easier we can create a simple javascript class to hold the data: function earthquake(item) { this.latitude = item.geometry.coordinates[1]; this.longitude = item.geometry.coordinates[0]; this.depth = item.geometry.coordinates[2]; this.usgsId = item.id; this.usgsCode = item.properties.code; this.tz = item.properties.tz; this.mag = item.properties.mag; this.time = item.properties.time; this.updated = item.properties.updated; this.place = item.properties.place; this.timestamp = new Date(); } The one tricky part here is that the identifier of the earthquake is the USGS ID, but all data in Azure Mobile Services uses a bigint as a primary key.  When we’re updating a row in Mobile Services, we’d pass the object into the update method with the appropriate ID (bigint).  (Deletes require the bigint ID only.)  Yes, this is a slight inefficiency because WAMS uses the surrogate bigint, and the USGS prefers the natural key of the USGS ID, and we will, for simplicity sake, use both depending on the operation.  Because we’re requesting the data frequently, each item in the feed will have one of a few states:  it may be new (not in the database), it may be in the database already, or it may be in the database but the feed contains updated/revised values. function processData(json) { var quakesTable = tables.getTable('earthquakes'); var featureList = json.features; featureList.forEach( function (item) { var eq = new earthquake(item); quakesTable.where({ usgsId: eq.usgsId }).read({ success: function (results) { if (results.length > 0) { //record exists eq.id = results[0].id; eq.timestamp = new Date(); quakesTable.update(eq); } else { //record doesn't exist quakesTable.insert(eq); //send notification? //see next blog post } } }); } ); } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } As we iterate through the features, we create an earthquake object from each item.   We then check the table for a record with the same USGS ID property.  If it already exists, we’ll update the row with the information because details may have changed.  Otherwise, we’ll insert it.  There’s a general inefficiency here that we can deal with if we’re so motivated.  Each item results in a query to see if the item exists, and then a query to either update or insert.  We could simply build a stored procedure that handles either scenario so it’s one call, but because each feed contains about 10 items and this scheduled task is a server-side job, it’s not high on my priority list.  With higher volume apps and/or with client apps, this is a modification you should make. The other nice thing we can do is send notifications when a new earthquake is found.  For example, if a new earthquake is found in the feed, we can send a live tile notification which would update the tile to look like so:   For Windows 8 apps, this is really a must-do feature.  Do _something_ (anything!) with the live tile – this will differentiate your app.  Mobile Services can send notifications to Windows Phone, Windows 8, iOS, and Android, so this is a great way to take the app cross platform.  In the next post, we’ll look at how to do a live tile update like the one above.

Microsoft DevRadio: (Part 7) Using Windows Azure to Build Back-End Services for Windows 8 Apps – Authentication Tips and Tricks

At long last!  Our final installment to the series – check it out! About this Video: Wrapping up their  “Using Windows Azure to Build Back-End Services for Windows 8 apps” series Brian Hitney , Andrew Duthie  and Peter Laudati, as they showoff some useful tips and tricks around authentication for your Windows Azure Mobile Server based apps. Tune in as they enable persistent login for a mobile service, and then discuss how we can get additional information about users from the configured identity provider(s).  Check out the full article here. Watch Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | Part 6 After watching this video, follow these next steps: Step #1 – Try Windows Azure: No cost. No obligation. Start your FREE trial now. Step #2 – Download the Tools for Windows 8 App Development Step #3 – Start building your own Apps for Windows 8 Subscribe to our podcast via iTunes or RSS If you're interested in learning more about the products or solutions discussed in this episode, click on any of the below links for free, in-depth information: Blogs & Articles: Brian Hitney’s blog Peter Laudati’s blog Andrew Duthie’s Blog Article:  “Getting user information on Azure Mobile Services” Article:  “Using Azure Mobile Services authentication” Videos: Microsoft DevRadio: How to Get Started with Windows Azure Microsoft DevRadio: (Part 1) What is Windows Azure Web Sites? Microsoft DevRadio: (Part 2) Windows Azure Web Sites Explained Microsoft DevRadio: How to Integrate TFS Projects with Windows Azure Web Sites Virtual Labs: MSDN Virtual Labs: Windows Azure Download MP3 (Audio only) MP4 (iPod, Zune HD) High Quality MP4 (iPad, PC) Mid Quality MP4 (WP7, HTML5) High Quality WMV (PC, Xbox, MCE)

Creating a Great Mashup using Windows Azure

This post details features used by Earthquake Explorer, a Windows 8 app that displays earthquake information on Bing maps.   Earthquake Explorer was based off of the Earthquakes mashup starter kit on github. Creating a mashup is pretty easy in Windows 8 – creating a great one requires a bit more work.   In this case, I'm working with the USGS earthquake GeoJSON feeds, a very easy-to-use feed that contains earthquake information for either the past hour, day, week, or month.   Overall, it’s a pretty ideal feed.  But, if you search for and install virtually any earthquake app in the store, you’ll see the limitations quickly.  While some apps allow some lightweight filtering of the data, there really isn’t a concept of search, pagination, and server-side filtering. To solve these limitations, we’d typically need to build out a fairly robust back-end server; fortunately, Windows Azure Mobile Services makes this really easy so let’s get started. First thing you need is a Windows Azure account (here’s a link to get a free trial).  To get the pricing stuff out of the way first:  Windows Azure Mobile Services currently offers a free tier (even beyond your trial), however, quite likely you’ll want to use a database behind the scenes, and that starts at $4.95/mo.  EDIT:  Good news!  SQL Databases now offers a free tier for up to 20MB databases. Multiple Mobile Services can share the same database as they are all schematized.  With your account ready to go, log in to the Windows Azure portal and select  Mobile Services in the left nav.   Next, click the New button in the bottom left to create a new Mobile Service (which I’ll just refer to as WAMS).  The New flyouts are context aware, so it should be ready to create a new WAMS but, just to verify, you should see something like this: After a few moments your service is set up and ready to go.  You will need to create a new SQL Database if you don’t already have one.  The default page of your WAMS should look like this, and it’s full of great info for creating new or leveraging WAMS in existing apps: Let’s click on the data link highlighted above to create a table to store our data.  We’ll call it ‘earthquake’, and we’ll also make it so only scripts and admins can modify the table, all users can read the table, like so: By default, WAMS is configured with dynamic schema, which means we can start inserting right away and the columns will be added dynamically to fit the objects we pass in.  This is perfect for development.  The next thing we’ll want to do is go over to the scheduled jobs page: After clicking create a scheduled job, give it a name like ‘fetchquakes’ and leave it run on demand only.   The job will be created and if you are looking at the details of the job by clicking on it, you’ll see a fairly empty screen – we don’t care about the configuration and schedule right now, we simply want to add a script that runs as part of our job.  Click the script button: Let’s start with a simple script.   Ideally we’ll go out to the service and use live data, but this will get us started: function fetchquakes() { var eq = {place: "Los Angeles", mag: 5.3, timestamp: new Date()}; var quakesTable = tables.getTable('earthquake'); quakesTable.insert(eq); }   .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } If we run this script (by clicking the Run Once button near the bottom/middle of the screen) and then navigate over to our table in the Data tab, we’ll see the row in the table: The nice part about this, too, is that it did a good job of figuring out the column types: However, we could go into the database itself and change the column definition if we wanted to.  We’ll wrap up the post here to keep this from becoming a book, but in the next post we’ll dive a bit deeper into consuming the live feed and storing that in the database.

Microsoft DevRadio: (Part 5) Using Windows Azure to Build Back-End Services for Windows 8 Apps – Adding Push Notifications

Abstract: In Part 5 of of their “Using Windows Azure to Build Back-End Services for Windows 8 apps” series Peter Laudati, Brian Hitney and Andrew Duthie  show us how to quickly add the ability to implement push notifications for his GameLeader Service using Azure Mobile Services. Check out the full article here. Watch Part 1 | Part 2 | Part 3 | Part 4 After watching this video, follow these next steps: Step #1 – Try Windows Azure: No cost. No obligation. 90-Day FREE trial. Step #2 – Download the Tools for Windows 8 App Development Step #3 – Start building your own Apps for Windows 8 Subscribe to our podcast via iTunes or RSS If you're interested in learning more about the products or solutions discussed in this episode, click on any of the below links for free, in-depth information: Register for our Windows Azure Hands-on Lab Online (HOLO) events today! Windows Azure Hands-on Labs Online Blogs: Brian Hitney’s blog Peter Laudati’s blog Andrew Duthie’s Blog Videos: Microsoft DevRadio: How to Get Started with Windows Azure Microsoft DevRadio: (Part 1) What is Windows Azure Web Sites? Microsoft DevRadio: (Part 2) Windows Azure Web Sites Explained Microsoft DevRadio: How to Integrate TFS Projects with Windows Azure Web Sites Virtual Labs: MSDN Virtual Labs: Windows Azure Download MP3 (Audio only) MP4 (iPod, Zune HD) High Quality MP4 (iPad, PC) Mid Quality MP4 (WP7, HTML5) High Quality WMV (PC, Xbox, MCE)

Microsoft DevRadio: (Part 4) Using Windows Azure to Build Back-End Services for Windows 8 Apps – Azure Mobile Services

Abstract: In Part 4 of of their “Using Windows Azure to Build Back-End Services for Windows 8 apps” series  Peter Laudati, Brian Hitney and Andrew Duthie show us how to build the same game leaderboard service on top of Windows Azure Mobile Services. Tune in as Andrew demos for us how to get started as well as lays out what some of the +/- are for using Azure Mobile Services for this kind of service.  Check out the full article here. Watch Part 1 | Part 2 | Part 3 After watching this video, follow these next steps: Step #1 – Try Windows Azure: No cost. No obligation. 90-Day FREE trial. Step #2 – Download the Tools for Windows 8 App Development Step #3 – Start building your own Apps for Windows 8 Subscribe to our podcast via iTunes or RSS If you're interested in learning more about the products or solutions discussed in this episode, click on any of the below links for free, in-depth information: Register for our Windows Azure Hands-on Lab Online (HOLO) events today! Windows Azure Hands-on Labs Online Blogs: Brian Hitney’s blog Peter Laudati’s blog Andrew Duthie’s Blog Videos: Microsoft DevRadio: How to Get Started with Windows Azure Microsoft DevRadio: (Part 1) What is Windows Azure Web Sites? Microsoft DevRadio: (Part 2) Windows Azure Web Sites Explained Microsoft DevRadio: How to Integrate TFS Projects with Windows Azure Web Sites Virtual Labs: MSDN Virtual Labs: Windows Azure Download MP3 (Audio only) MP4 (iPod, Zune HD) High Quality MP4 (iPad, PC) Mid Quality MP4 (WP7, HTML5) High Quality WMV (PC, Xbox, MCE)

Microsoft DevRadio: (Part 2) Using Windows Azure to Build Back-End Services for Windows 8 Apps

Abstract: Peter Laudati, Brian Hitney and Andrew Duthie are back for part 2 of their series and in today’s episode Andrew shows us how to deploy the OData Service for his Windows 8 app to Windows Azure as well as outlines the advantages and disadvantages to building back-end services via this approach. After watching this video, follow these next steps: Step #1 – Try Windows Azure: No cost. No obligation. 90-Day FREE trial. Step #2 – Download the Tools for Windows 8 App Development Step #3 – Start building your own Apps for Windows 8 Subscribe to our podcast via iTunes or RSS If you're interested in learning more about the products or solutions discussed in this episode, click on any of the below links for free, in-depth information: Register for our Windows Azure Hands-on Lab Online (HOLO) events today! Windows Azure Hands-on Labs Online Blogs: Brian Hitney’s blog Peter Laudati’s blog Andrew Duthie’s Blog Videos: Microsoft DevRadio: How to Get Started with Windows Azure Microsoft DevRadio: (Part 1) What is Windows Azure Web Sites? Microsoft DevRadio: (Part 2) Windows Azure Web Sites Explained Microsoft DevRadio: How to Integrate TFS Projects with Windows Azure Web Sites Virtual Labs: MSDN Virtual Labs: Windows Azure Download MP3 (Audio only) MP4 (iPod, Zune HD) High Quality MP4 (iPad, PC) Mid Quality MP4 (WP7, HTML5) High Quality WMV (PC, Xbox, MCE)

Dark Skies for Windows 8 Updated

I’m happy to finally have the next update to Dark Skies in the Windows 8 store!  In the initial release, I used Bing Maps to display light pollution data.  In this version, I allow users to display and share favorite viewing spots, and spruced up the live tile with some cool info. The main page can display information about a pin on the map: Admittedly, there aren’t too many pins just yet, but it will grow over time.   It’s not just favorite viewing locations – astronomy shops, user groups and clubs, and events can all be added.  Also, the live tile now displays some useful moon info: The tile displays the current phase of the moon, as well as the rise and set times (if location services is enabled).  The little + (or –) signs indicates the set or rise occurs on the next or previous day, so for me, the moon rises at 1:14 p.m. and sets tomorrow at 3:45 a.m. Technical Info This is a developer blog, after all.   Everything in this release relies on Windows Azure Mobile Services (WAMS).   The service for the live tiles is hosted in Windows Azure Web Sites, and Windows Azure Mobile Services does the authentication and single-sign on, and also serves notifications when new sites are added.  For example, if there’s a new site added near any of the user’s home locations, a new tile with a Bing map is sent down as a notification, while the badge displays the total number of new nearby points since last run: It’s been a lot of fun to develop, and really, it would’ve been too much work without having WAMS to power everything.   The bulk of the work was getting things to look just right, rather than fiddling with authentication code and developing a back end system.   I’ve also been using TFS in the cloud to store source code, and do continuous integration with the Windows Azure Web Site (an ASP.NET MVC 4 controller that serves XML as tiles.)

Scrubbing UserId in Windows Azure Mobile Services

First, many thanks to Chris Risner for the assistance on this solution!   Chris is part of the corp DPE team and has does an extensive amount of work with Windows Azure Mobile Services (WAMS) – including this session at //build, which was a great resource for getting started. If you go through the demo of getting started with WAMS building a TodoList, the idea is that the data in the todo list is locked down to each user.   One of the nice things about WAMS is that it’s easy to enforce this via server side javascript … for example, to ensure only the current user’s rows are returned, the following read script can be used that enforces the rows returned only belong to the current user: function read(query, user, request) { query.where({ userId: user.userId }); request.execute(); } If we crack open the database, we’ll see that the userId is an identifier, like the below for a Microsoft Account: MicrosoftAccount:0123456789abcd When the app connects to WAMS, the data returned includes the userId … for example, if we look at the JSON in fiddler: The app never displays this information, and it is requested over SSL, but it’s an important consideration and here’s why.   What if we have semi-public data?   In the next version of Dark Skies, I allow users to pin favorite spots on the map.  The user has the option to make those points public or keep them private … for example, maybe they pin a great location for stargazing and want to share it with the world: … Or, maybe the user pins their home locations or a private farm they have permission to use, where it might be inappropriate to show publically. Now here comes the issue:  if a location is shared publically, that userId is included in the JSON results.  Let’s say I launch the app and see 10 public pins.  If I view the JSON in fiddler, I’ll see the userId for each one of those public pins – for example: Now, the userId contains no personally identifiable information.   Is this a big deal, then?   It’s not like it is the user’s name or address, and it would only be included in spots the user is sharing publically anyway. But, if a hacker ever finds a way to map a userId back to a specific person, this is a security issue.  Even my app doesn’t know who the users really are, it just knows the identifier.  Still, I think from a best practice/threat modeling perspective, if we can scrub that data, we should.  Note: this issue doesn’t exist with the todo list example, because the user only, and ever, sees their own data. Ideally, what we’d like to do is return the userId if it’s the current user’s userId.  If the point belongs to another user, we should scrub that from the result set.   To do this via a read script in WAMS, we could do something like: function read(query, user, request) { request.execute( { success: function(results) { //scrub user token if (results.length > 0) { for (var i=0; i< results.length; i++) { if (results[i].UserId != user.userId) { results[i].UserId = 'scrubbeduser'; } } } request.respond(); } }); } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }If we look at the results in fiddler, we’ll see that I’ll get my userId for any of my points, but the userId is scrubbed if it’s another user’s points that are shared publically: [Note: these locations are random spots on the map for testing.] Doing this is a good practice.  The database of course has the correct info, but the data for public points is guaranteed to be anonymous should a vulnerability ever present itself.   The downside of this approach is the extra overhead as we’re iterating the results – but, this is fairly minor given the relatively small amounts of data. Technical point:  In my database and classes, I use Pascal case (as a matter of preference), as you can see in the above fiddler captures, such as UserId.   In the todo example and in the javascript variables, objects are conventionally camel case.   So, if you’re using any code here, just be aware that case does matter in situations like this: if (results[i].UserId != user.userId) // watch casing! .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Be sure they match your convention.   Since Pascal case is the standard for properties in C#, and camel case is the standard in javascript, properties in .NET can be decorated with the datamember attribute to make them consistent in both locations – something I, just as a matter of preference, prefer not to do: [DataMember(Name = "userId")] public string UserId { get; set; }

Best Practice for Sending Windows 8 Tiles from Mobile Services

Those that know me know I am not a fan of javascript, in pretty much all of its forms (including node.js), however, I’m really digging Windows Azure Mobile Services (WAMS).  WAMS allows you to easily provide a back end to applications for storing data, authenticating users, and supporting notifications on not just Windows and Windows Phone, but also iOS with future plans of supporting Android soon. Now, I mention javascript because WAMS provides a slick node-like powered data service that makes it really easy to store data in the cloud.  The ToDoList example exercise illustrates the ease at storing user data in the cloud and hooking it up with authentication and notification support.   The nice thing about the authentication is that it’s easily integrated into the backend: But, more on this later.  Right now, I want to deal with notifications in WAMS.  In WAMS, you have the opportunity to right custom server-side javascript to do things like send notifications on insert/update/delete/read access: In my case, I want to send a tile update if the new data meets some criteria.   Let’s start all the way down the code and work our way out, starting with the notification piece.    One page you MUST have bookmarked is the tile template catalog on MSDN.   This page defines the XML syntax for all possible tiles your tile can have, including both small/square tiles, and large/wide tiles.    All of these have a defined schema, such as this for TileSquarePeekImageAndText04: <tile> <visual> <binding template="TileSquarePeekImageAndText04"> <image id="1" src="image1" alt="alt text"/> <text id="1">Text Field 1</text> </binding> </visual> </tile> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Which produces a tile that “peeks”, such as this (which flips between the top half and bottom half): Yes, it’s easy to laugh at the magic “04” in the template title.  I like to joke that my personal favorite is TileWideSmallImageAndText03.   But, there variety is crucial to creating the ideal app experience and that depends on how you want to display the data -- and that requires knowing the XML template. Now, in WAMS, there’s a great tutorial on sending some basic notifications.   In that walkthrough, a notification is sent via the server-side javascript like so: push.wns.sendTileSquareText02(“https://bn1.notify.windows.com?[snip]”, { text1: “some text”, text2: “more text”}); .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Now, at first glance, this is very nice because WAMS will write the XML for you.  However, you still must know what data the template requires.  Does it need an image?  One text line?  Two?   You get the point.  Unsurprisingly, calling that method will generate XML like: <tile> <visual> <binding template="TileSquareText02"> <text id="1">some text</text> <text id="2">more text</text> </binding> </visual> </tile> You can learn more about this in the WAMS script reference.  Another must-have bookmark.  However, I recommend you don’t use these at all, and instead write the XML payload directly.   This is for a few reasons, but primarily, it’s for control – and, really, you have to know the fields required anyway and you’ll still have the tile catalog page open for reference. In looking at the mpns (Microsoft Push Notification Service) library a bit closer (awesome job by the guys, by the way) up on git, it has this method: var raw = new mpns.rawNotification('My Raw Payload', options); .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } When developing my app, I realized I had no idea what tile size the user has.   Some may opt to use a wide tile, others a small tile.  I needed different tiles to support both.   I didn’t like sending two notifications (seems wasteful, doesn’t it?) and to do this efficiently, it’s easier to just create the payload explicitly that includes all tiles.  For example, this includes two completely different tiles: var payload = "<tile><visual><binding template='TileWideImageAndText02'>" + "<image id='1' src='" + xmlEscape(bigImage) + "' alt='map'/>" + "<text id='1'>" + text1 + "</text>" + "<text id='2'>" + text2 + "</text>" + "</binding>" + "<binding template='TileSquareImage' branding='none'>" + "<image id='1' src='" + xmlEscape(smallImage) + "' alt='map'/></binding></visual></tile>"; push.wns.send(channelUri, payload, 'wns/tile', { client_id: 'ms-app://<snip>', client_secret: 'i will never tell', headers: { 'X-WNS-Tag' : 'MainTile' } }... .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Sure, it doesn’t look as clean and (gasp!) we have to do string concatenation.   But, it’s only a couple of minutes more work and just more flexible.  Like I said: either way, you need to know the template.   In my case, I’m sending both notifications in one payload.  The first is TileWideImageAndText02, which produces a nice image with the text on the bottom describing the image.  If the user has a small tile, it will use TileSquareImage, which basically just forgoes the text and just displays the image.  After trying a few, I settled on this combination as the best user experience.  This is an easy way, with minimal effort, to support both wide and narrow tiles. As an aside, I recommend setting the tag (X-WNS-Tag) header, particularly if your app cycles tiles and you want to replace a specific tile.  Also, it’s a good ideal to XML escape all data, which I’m doing with the long image URLs … and this, I believe, is taken right from the mpns library: var xmlEscape = function (text) { return text.replace(/&/g, '&amp;') .replace(/</g, '&lt;') .replace(/>/g, '&gt;') .replace(/"/g, '&quot;'); } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } If you don’t escape the data and have some illegal chars in there as a result, the notification gets sent correctly (that is, accepted), but gets ignored by the client. Now that I’ve got the basic code to send a tile, I needed to filter some data and run a query and sort users by distance.  Sound like fun?  I’ll write about that next…

My Apps

Dark Skies Astrophotography Journal Vol 1 Explore The Moon
Mars Explorer Moons of Jupiter Messier Object Explorer
Brew Finder Earthquake Explorer Venus Explorer  

My Worldmap

Month List