IntelliJ and Google Maps

Recently, I decided to jump platforms from Windows Phone to Android.  Frankly, I got sick and tired of being a second class citizen on Windows Phone in terms of app deployments.  My how Android has changed in the years since I left it, it is really something to see and use; fantastic operating system.

So I decided it was time to take my Bathroom Review app to Android, even more necessary as my data connection with the Windows Phone no longer works after being deactivated from my Verizon account.  Now, you would think that it being Google, adding a Google Map would be easy (it certainly is on Windows Phone), well, it isn’t, and even worse, I use IntelliJ and most of the tutorials are focused on Eclipse.  So here is how I got it to work with IntelliJ.

Google Play Services

So the entire library involved in using Google Maps is housed in a separate library called “Google Play Services”.  For starters, just getting the 4.x SDK will NOT give you this library, you have to download it separately from under ‘Extras’.
image

Once you have it installed you have to reference it in a way very similar to how libraries are referenced in iOS, as in project module references.  In IntelliJ this can be somewhat tricky and took me a ton of time to really figure out.  The first step is to import the ‘Google Play Services’ code into your project.  You will find the option to do this by opening the Module Settings dialog for YOUR project and selecting the Modules selection.

Right click on your project and select the Add –> Import Module option (alternatively, you can use the + button).  The library is located at /extras/google/google_play_services/libproject/google-play-services_lib/google-play-services_lib.iml (notice: I am referencing the IML file, this is for IntelliJ, a similar file is referenced in the Eclipse import process.
image

Now this is the important part.  You have to add this as BOTH a module dependency AND a library dependency.  This simply involves clicking the + icon for your module and adding a module dependency:
image

And then doing the same again but this selecting library and selecting Google Play Services as a library.
image

The reason for this is, the module dependency will ensure that certain resources (references in the R class) are available in your project, while the library reference will ensure standard code classes are available.  Personally, I would rather not have to worry about this and I believe Android should just provide this as part of the runtime.  In the end, your screen should look something like this:
image

To ensure that Google Play Services is available, create an activity and create a layout to reference.  In the layout, make sure the following XML is present for the layout:

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
              android:id="@+id/map"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:name="com.google.android.gms.maps.MapFragment" />

.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; }

IntelliJ will color red the packages and classes it cannot find, even in XML (as of IntelliJ 12).  If anything is red here, something is wrong with your library reference.  This is also how you bring the Map into a view so the user can interact with it.  One final check, to make sure you have access to the appropriate R class that Play Services will use, attempt to write this line of code.  If you can auto-complete this in IntelliJ your module reference is correct.

com.google.android.gms.R

.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 that works, congrats, your references are golden, you are now halfway through the battle.

Getting an API Key

To use Google Maps you will need an API key from Google.  Getting one is pretty easy.  I am going to assume you already have a Google Developer Account setup (I believe if you have a Google Account you can activate the developer console pretty easily).

To put it simply, you will need to create a Google Project, and associate that with an API key and setup the appropriate services.  I feel like this URL (https://developers.google.com/maps/documentation/android/start#creating_an_api_project) explains the process much better than I can.

Here is a look at my Manifest file to give you an idea of what you need to make sure you have in your file:
image

I am hiding my API Key for obvious reasons, but as you can see there is quite the plethora of permissions which are needed to use Maps.  Assuming everything is go there lets cover a few obscure things that need to be set right.

Open project.properties and ensure the following line exists in the file:

android.library.reference.1=../../android/extras/google/google_play_services/libproject/google-play-services_lib

.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; }

Notice that your path might be different than this.  The important thing is that a line like this exists.

Also, and this was the super obscure thing.  Ensure the following text exists in the proguard-project.txt file:

image

.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; }

I’ll be honest, I have no idea what this is doing or why it is necessary.  I got both of these tips from here: http://stackoverflow.com/questions/13696620/google-maps-android-api-v2-authorization-failure

Warning!!

So, I found this out the hard way, at present the emulator is NOT able to load Google Play Services which means the sole way to test this code is with a device.  Why this is the case is beyond me and really made me raise an eyebrow at Google (along with this whole process).  Perhaps this is so new (I only just went back to developing Android seriously) that the emulator hasn’t caught up.  But for whatever the reason, ensure that you are using a device when testing code using Google Maps with Google Play Services.  Additionally, if you start seeing some odd behavior or the Maps aren’t loading, trying uninstall and reinstalling the app on your device.

Conclusion

So this whole process took me about 4-6hrs to figure out, probably would’ve been longer without the help of a few people on the Android-Dev IRC channel.  I am always confused when I find things like this which seem way overcomplicated, especially when they are a part of the vendors business; as Google Maps is in this case.  On Windows Phone, you simply drop the tag down in Windows Phone 8 and that’s it.  I was surprised because usually Google is pretty much on par with Microsoft in terms of making things like this easy.  This combined with my reservations about Android Studio (in particular cause I think Gradle and its integration with AS need a lot of work) have made me a bit reserved about the developer story for Android.

I sincerely hope this helps someone because it was extremely frustrating going through this.  I hope this scenario is better supported with the next release of the Android tools.

Another good blog post about Google Maps: http://www.androidhive.info/2013/08/android-working-with-google-maps-v2/

Real Time Binding with Windows Phone

Recently while developing a new app for Windows Phone I ran into a strange problem.  Using Caliburn.Micro I set up a binding with a simple TextBox control.  Also on the page in an Application Bar Button which raises a Save action method in the view model.  The bug was that every time I saved the entity, the Name would be null in the backend service.  The debug process revealed that the Property Update for the Name was happening AFTER the Save method.

Reading the documentation and posts by other developers I discovered that the default mode for source updates happens on “Lost Focus” and that, for whatever reason, when the user presses an Application Bar Button the control does NOT actually lose focus, thus the property update happens AFTER the view model method is executed.  In Silverlight and WPF, you can set the UpdateSourceTrigger to PropertyChanged which will handle this case.

Unfortunately, for whatever reason, Windows Phone Silverlight does not support this feature so the only option is to update on focus, which obviously doesn’t work.  However, this feature is available with some support from the Microsoft Patterns & Practices Prism framework in the UpdateTextBindingOnPropertyChanged custom behavior.  Here is the source for the class:

   1:      public class UpdateTextBindingOnPropertyChanged : Behavior
   2:      {
   3:          private BindingExpression expression;
   4:   
   5:          protected override void OnAttached()
   6:          {
   7:              base.OnAttached();
   8:   
   9:              this.expression = this.AssociatedObject.GetBindingExpression(TextBox.TextProperty);
  10:              this.AssociatedObject.TextChanged += this.OnTextChanged;
  11:          }
  12:   
  13:          protected override void OnDetaching()
  14:          {
  15:              base.OnDetaching();
  16:   
  17:              this.AssociatedObject.TextChanged -= this.OnTextChanged;
  18:              this.expression = null;
  19:          }
  20:   
  21:          private void OnTextChanged(object sender, EventArgs args)
  22:          {
  23:              this.expression.UpdateSource();
  24:          }
  25:      }

.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; }

What this behavior is doing is attaching itself the given control and calling UpdateSource on a custom binding which will force the source to update.  In this case, we are associating this source update with the TextChanged event which will cause the property to update as the value of the Textbox changes. (Side note: you will also need to include the System.Windows.Interactivity to get the Behavior project).

Now, to actually use this class, you will need to write some code behind, just two lines.  There might be a way to get this into the declarative binding syntax in the XAML, but I do not know how to do that.  Here is the code which adds this behavior, it is in the constructor just after the InitalizeComponent.

        public SaveLocationView()
        {
            InitializeComponent();
 
            // manual bindings
            var behavior = new UpdateTextBindingOnPropertyChanged();
            System.Windows.Interactivity.Interaction.GetBehaviors(tbName).Add(behavior);
        }

.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; }

Very simple, hence why I didnt pursue trying to get it into the binding syntax.  This correctly fixes the problem with the updating.  I hope people find this helpful, and I do hope Microsoft makes this functionality native in future versions.

DevLink 2013

Last week I attended the DevLink 2013 conference Chattanooga, Tennessee.  I really must tip my hat to all the people that work together to put together such a great event.  The sessions were amazing and I absolutely love the people and networking events.  This year, the team brought in, among others, Scott Hanselman to keynote at lunch on the second day.  A fan of his Hanselminutes podcast I was not disappointed.  The keynote focused on JavaScript and showed off some of what is being written, and how Microsoft is constantly working to make JavaScript debugging and HTML debugging easier and easier leveraging Visual Studio.  I must admit though, the best part of the talk was the humor and pure entertainment value.  Scott has an amazing ability to make you chuckle and laugh but communicate necessary information.

My focus with regard to the sessions was SPA.  While I have not had as much of a chance to work on SPAs as I would like at Centare I still enjoy knowing how to use frameworks like Angular, Ember, and now Durandal which builds on top of the excellent MVVM provided by Knockout JS.  To that end, I also sat in on the Object Oriented JavaScript session.  The speaker, from AppendTo and clearly very knowledgeable on JavaScript, showed that by leveraging the proper native constructs that JavaScript can emulate the features of an object oriented language.  It was really neat and provided a glimpse into how framework designers do certain things to keep things more organized.

This was my second time attending DevLink, but it was my first time I had been accepted at a speaker.  After a good show at That Conference I was eager to prove I could handle speaking at larger conferences.  My talk started very well, some great information.  But then we got into the demos and I realized that I had not prepared as well as I should have.  I forgot to the grab the source for one of my demos, but I was able to use the Azure Management Portal to show off what would have been the result.  However, the central piece of the talk: the YouTube Voting Demo, fell apart.  I learned many things about keeping a demo on a USB stick, such as Windows 8 apps dont like their source code being on USB sticks, especially not those formatted with NTFS.

Needless to say, I was grateful most of my audience stuck with me, but I was horribly embarrassed and disappointed as I was not able to even get through my talk all the way.  Whether it was hardware or not, I obviously rested on my laurels after That Conference and assumed the code would work without me having touched it.  The only saving grace for me is, I am giving the same talk on Wednesday at Chicago Downtown .NET Developer Meetup, so its a quick chance for redemption.

But I refuse to let me poor performance take away from what was a productive and valuable conference going experience.  I look forward to attending next year as well.

Speaking at That Conference

For those not aware, the technology community of the Midwest has come together to create yet another amazing conference.  This was the second time That Conference (http://www.thatconference.com) was held at the Kalahari in Wisconsin Dells, and it was my first time attending. I really must give my thanks to Clark Sell and the rest of the planning committee for putting things together, I was very much reminded of Codemash (http://www.codemash.org).

Initially, I was not going to speak at That Conference but sometimes things happen and the outcome works in your favor. Josh Twist, the PM on the Windows Azure Mobile Services team at Microsoft, was initially slated to speak on Mobile Services, however, due to a scheduling conflict, ended up withdrawing.  I was very honored when he asked me to take his place. However, I decided my Push Notifications presentation was simply not appropriate for That Conference, I would need to discuss WAMS with a greater feature scope. This meant, creating an entirely new talk.  Thankfully, due to my commitments and other plans for August, Centare had been allowing me to remain relatively idle, I used this time to construct a new presentation, based largely on Josh’s BUILD 2013 talk.  I managed to complete the slide deck and demo’s within the week and thanks to the cooperation of my fellow Centarians, I was able to get in enough practice to make the presentation a rousing success at That Conference.

For me, it was a huge dream come true.  While I have been gratefully chosen to speak at many conferences in the past, That Conference was by far the biggest and most visible one to date; I have been trying to speak at Codemash for three years, but its not easy, there are MANY good speakers out there.  I was very thrilled and happy to share my views on Azure Mobile Services with the attendees at That Conferece.  I look forward to a success engagement next week at DevLink in Chattanooga, Tennessee and, with some luck, I will get to speak at Codemash in January of 2014.

Thanks again to That Conference for allowing me to speak and thanks to everyone who came and enjoyed my session.

Performing Persistent Authentication with Mobile Services

In previous entries I talked about what Mobile Services can provide in terms of authentication, but how do you actually use it?  That answer is quite simple.

private async void MainPage_Loaded(object sender, RoutedEventArgs e)
{
    try
    {
        var client = new MobileServiceClient("APP URL", "APP KEY");
        var user = await client.LoginAsync(MobileServiceAuthenticationProvider.Facebook);

        // do something
    }
    catch (InvalidOperationException)
    {
        MessageBox.Show("Login Failed");
    }
}

.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; }

In this example, we are forcing the user to login each time the application starts.  This does a few things:

  • Negates the need for us to store the User Id on the device.  Since the UserId will be used as a key value, we will need to obtain this value in some way
  • If using a singleton approach to handling your Mobile Service Client reference this will automatically set the internal authentication of the client
  • OAuth dictates that the underlying tokens used for authorization expire after a given amount of time.  By leveraging this approach, Mobile Services can be allowed to check whether the token is expired or not and issue new ones

So the experience for the user is the application starts and, if it is the first time or the user has not granted rights to the app for their social profile (Facebook in this case) they will be presented with the touch friendly Facebook login.  Subsequent application launches will bypass the login screen and return the UserId as stored by Mobile Services.  This ID is of the form:

: Numeric value

This value is very important.  Its quite normal to use this as the key value for user specific data in your Mobile Services tables. While the above process ensures the token is expired, it is recommended that the application NOT log in each time.  To improve the user experience, you should be caching this value on the device.  Using this value (and the associated Mobile Service Token obtained from the MobileServiceUser object coming from the Login operation), at the conclusion of each request verify that a 401 (Unauthorized) is not received.  If it is received than the Login flow must be executed.

Josh Twist has an excellent on handling this case here: http://www.thejoyofcode.com/Handling_expired_tokens_in_your_application_Day_11_.aspx

Quick note: The concept of a “filter” was renamed to “HttpMessageHandler”.  The third parameter to the constructor for MobileServiceClient which represents an array or these “interceptors”.

Additional documentation can be found here: http://msdn.microsoft.com/en-us/library/windowsazure/system.net.http.httpmessagehandler.aspx

Azure Mobile Service Authentication

It is quickly becoming the case that writing login systems for applications is a superfluous activity; especially when it comes to mobile applications.  Everyone now has Facebook, Twitter, Google or some combination therein.  Being able to leverage these services for authentication is huge because it alleviates the need to maintain separate logins and allows you access to data that the user would otherwise have to re-enter on your site, data is likely going to be as up to date as you may want it to be.

Most services use Open Authentication (OAuth) which allows an application to interact with something like Facebook on the user’s behalf.  Naturally, this comes with many caveats for both sides and thus the protocol is very exacting on what an application must do to be trusted.  I will not spend much time talking about the OAuth spec, I will only say there are at least three values you need to be aware of:

  • Consumer Key – a key value which identifies your app to the given service
  • Consumer Secret – an additional value used in identifying you app to a given service
  • Access Token – a generated key value which symbolizes a relationship between your app, a user, and a service
  • Access Token Secret (optional) – a generated value used in creating a trust relationship between your app, the user, and the service.  This is not always present in the workflow

Luckily, thanks to the popularity of OAuth a number of frameworks have emerged to help abstract the workflow associated with authenticating users.  One such abstraction is the Azure Mobile Services Authentication.

After logging into the Azure Management Portal, find your Mobile Service and select the ‘Identity’ tab.

image

Within this tab you will find space to enter a series of values for each service.  Azure Mobile Service will use these values during the Login operation to obtain the appropriate OAuth values for the user; this allows the user to authenticate with your Mobile Service and make calls to tables that require User Authentication for calls to be executed.

On the device itself, creating this authentication is a simple as this (in C#):

var client = new MobileServiceClient("YOUR MS URL", "YOUR APP KEY");
var user = await client.LoginAsync(providerType);

.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; }

In this example, I am defining the client instance at the function level however, I recommend calling using a Singleton to ensure the same MobileServiceClient instance is used each time. The reason for this is you may choose to restrict access to your tables to “User”.  To understand this concept it is important to first think of your tables as REST endpoints.  The permissions you set dictate who can access the endpoint.  In this way you can quickly setup a user driven system without having to write your own login system (just use Facebook, Twitter or another supported platforms).

So, if you will be making calls into other tables using ‘User’ permission a Singleton approach will assist you in ensure the client maintains its authentication. Otherwise you will need to store the UserId and the generated MobileServiceAuthenticationToken for use in subsequent requests.

Why am I telling you about all this?  Well if you are going to carry out operations against Facebook, Twitter, or any other service which uses OAuth for authorization you will need at least an Access Token and in some cases an Access Token Secret (Twitter).  Without this/these value(s) you will not be able to access the respective API to do anything useful.  Unfortunately, the result from Login does not expose these values; this is intentional.

Disclaimer: when dealing with an OAuth system the Access Token (and optional secret value) are EXTREMELY sensitive values which should not be shared with anyone and NEVER transmitted over http (https is fine and is what Mobile Services defaults to).  For this reason, the Azure Mobile Service Login calls does NOT automatically return these values.  However it is possible to get and store them.  Here is an insert trigger that I wrote which saves all user information:

Disclaimer: At the present time the Azure Mobile Service authentication framework does NOT allow the specification of additional Facebook scope values.  This means that using Azure Mobile Services to get the access token will only give you access to the the user’s friend list and their information.  No posting to their wall or anything advanced.  In order to achieve this at present it is necessary to generate the access token outside Mobile Services and then pass that access token to the Azure Mobile Service Authentication framework, described here: http://ntotten.com/2013/03/14/using-windows-azure-mobile-services-with-the-facebook-sdk-for-windows-phone/

function insert(item, user, request) {
     var usersTable = tables.getTable("Users");
     usersTable.where({
          UserId: item.UserId
     }).read({
          success: function(results) {
               // get user identification information
               var identity = user.getIdentities();
                
               // update the item based on the authentication
               if (identity.twitter) {
                    item.AccessToken = identity.twitter.accessToken;
                    item.AccessTokenSeret = identity.twitter.accessTokenSecret;
                }

               if (results == 0) {
                    // insert the new user
                    request.execute();
               }
               else {
                    request.respond(200, item);
               }
          }
    })
}

.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; }

The key here is the call to user.getIdentities().  Mobile Services is tracking the user behind the scenes with all of the appropriate access token and (optional) secret information.  Note: Only Twitter requires the secret, all other providers will have this field empty.

By adding the AccessToken and AccessTokenSecret fields to the item JSON object when request.execute() is called Azure Mobile service will not only store these values for us, it will also create the columns (assuming Dynamic Schema is turned on for at least the first execution).  If the user already exists, we do nothing but respond with the item and status code 200 (Completed).

Either way when this operation completes our Users table will have a row with 5 columns:

  • id – this is a generated column by Azure Mobile Services, it serves as the default primary key
  • UserId – this is a value which is sent back after the Login operation.  An example value might be: “Twitter: 123456”.  I tend to store this value locally on my device and then use it as a look up to get the rest of the information
  • Token – This is the MobileServiceAuthenticationToken which comes down (along with the UserId as the result of the Login operation).  This values is necessary when making User Authenticated Requests to a Mobile Service table
  • Access Token – as shown above this is taken from the result of getIdentities() when called on a non-null user parameter.
    • The user parameter will be non-null when the client is provided with information (UserId and Token) to authenticate the request for the user
  • Access Token Secret – taken from the same, only needed with Twitter

Now, with this information in place we can easily, at startup get the needed information to make our calls to the third party service we are using.

My App

So, understanding how this authentication works let’s look at a quick example.  This first part returns an object representing a user authenticated by Mobile Services.

var client = new MobileServiceClient("APP URL", "APP KEY");

if (providerType == MobileServiceAuthenticationProvider.Facebook)
{
    var fbAuthClient = new FacebookSessionClient(
                 Application.Current.Resources["FacebookAppId"].ToString());
    var authResult = await fbAuthClient.LoginAsync("publish_actions");
    var token = JObject.FromObject(new {access_token = authResult.AccessToken});

    user = await client.LoginAsync(providerType, token);
}
else
{
    user = await client.LoginAsync(providerType);
}

.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; }

What is happening here is we are requesting an access token from Facebook via the FacebookSessionClient class.  This will handle visual transition as well. Note: my current goal is determine how to use the FacebookClient class entirely to do this, as the session client comes in a different library.

The login method for Mobile Services supports the transmission of a secondary token, which you can use to provide existing login information, if it is not provided Mobile Services will attempt to generate it for you.  For Facebook, if you intend to do more than read the user’s profile information, you do NOT want Mobile Services generating the access token.  Notice the “publish_actions” permission being passed which allows the app to publish to the user’s wall.

The next step is saving the login information to the server (invoking the insert script above).  This is done via the InsertAsync method:

var table = client.GetTable("Users");
await table.InsertAsync(user.AsToken());

.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; }

Next, you will want to save the UserId value from the Login locally so it can be used as a lookup key on application start to get the access token.  This will be needed 1) to make authorized calls against the APIs and 2) you will want to check the token is not expired (they dont last forever, 2 months on Facebook).  I decided to make use of Isolated Storage to store my tokens

I will admit that finding out the shortcoming of the Facebook support in Mobile Services was surprising, it does not exist in Twitter.  In my opinion the reason the definition of scope doesnt exist within Azure Mobile Services is simply a timing thing.  And I think it is something that we will see coming down the pipeline in the near future.

Accessing the Twitter API with Mobile Services

If you have been reading at all about Azure Mobile Services you know that the system supports authentication through 4 different third party providers: Facebook, Twitter, Google Plus, and Windows Live (or whatever they are calling it these days).  The setup for your Mobile Service must precede any code that you write.  This process involves gathering consumer keys and secret and making your mobile service aware of them.  The folks at Microsoft have some excellent documentation around this: http://www.windowsazure.com/en-us/develop/mobile/tutorials/get-started-with-users-dotnet/

By using one of these methods you effectively off load the handling of authentication to the appropriate site.  This is becoming a very common approach to authentication due to the proliferation of these services.  Here is a quick example of how to do do this authentication in Azure Mobile Services:

        private async void btnAuthorize_OnClick(object sender, RoutedEventArgs ev)
        {
            var client = new MobileServiceClient("Your Mobile Service Url", AppKey);
            var userData = await client.LoginAsync(Provider);
        }

.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; }

This is very simple and straightforward.  Running this code should cause the appropriate login form to come in.  The form and associated window should disappear if authentication is successful.

If we look at userData we will see two values within: UserId and MobileServiceAuthenticationToken.  Depending on what you intend to use the authentication for you may wish to save one or both values:

  • If you intend to configure some or all actions on a Mobile Service endpoint (table) to require user authentication you will NEED to know the MobileServiceAuthenticationToken when making those requests along with the UserId
  • If you intend (as I will show to look a user up to get additional information, I recommend the UserId value)

For the purposes of this exercise we will be storing just the UserId value.  The general process beyond this point is, when the app starts up, attempt to get this UserId value and look for it in an Azure Mobile Service endpoint (table).  If found, download additional information that will be useful for access the related API, for example OAuth Access token information.

For whatever reason, the existing Login method does NOT return to your application the OAuth information these services use.  However, it is available to you with a special call within your REST endpoint.  Here is an example of the insert trigger which I call after the user has successfully logged in to a service, in my case Twitter:

function insert(item, user, request) {

    var identity = user.getIdentities();
    var userId = identity.twitter.userId;
    var accessToken = identity.twitter.accessToken;
    var accessTokenSecret = identity.twitter.accessTokenSecret;
    
    var identityTable = tables.getTable("identity");
    var insertItem = {
      userId: userId,
      accessToken: accessToken,
      accessSecretToken: accessTokenSecret  
    };

    identityTable.insert(insertItem, {
        success: function(result) {
          request.respond(200, insertItem);
        },
        error: function(code) {
            console.log(code);
            console.log("Something went wrong");
            request.respond(500);
        }
    });
}

.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; }

The key call here is getIdentities() on the user object. In this way you can get additional information for a particular user.  Remember, however, that you will get null if the user is not authenticated.  To be certain of this, I recommend the table require user authentication for the given action.

My recommendation here is to call this trigger immediately after the user is verified via Login, as all of the information needed will be available at that point.  Once you insert the user with the access token and secret, you need only look up the user to get this information, hence why it was mentioned that the UserId should be stored and used a lookup key.

In addition, the script above sends the new identity object as part of the response to the caller.  This gives the caller immediate access to the Access Token and Access secret.

Getting a List of User Status Updates from Twitter

Disclaimer: the process I am going to show will rely on RestSharp (http://www.restsharp.org) to make REST calls to the Twitter API.  Because of this approach I will be showing how to actually build an authorized request.  This process is very tedious and error prone, I recommend using an SDK instead when doing this sort of thing in production.

Now that you have the Access Token and Secret you can make calls to Twitter.  Making calls to Twitter, however, is not easy and requires a lot of setup with respect to the request being made.  Full details are available here: Authorizing a request

At the center of authorizing a Twitter request is the Authorization header value.  The value of this header is comprised of encoded values from all parameters given to the request.  Here is a list:

Consumer Key  this is the value given to you through the Twitter developer console to identify you application.  This value will remain constant through the life of your application. Parameter name: oauth_consumer_key

Nonce – This one confused me for the longest time.  All it is really is a random string designed to identify the request to Twitter.  Generate this once per request.  Here is the code I used to generate mine:

        private string GenerateNonce()
        {
            return Guid.NewGuid().ToString().Replace("-", string.Empty);
        }

.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; }

Parameter Name: oauth_nonce

Signature – this is probably the most annoying one.  It is Base64 encoded string representing all other parameter values given to the request.  I will describe this process later, but this is how Twitter explains it: https://dev.twitter.com/docs/auth/creating-signature

Signature Method – this is a constant value of “HMAC-SHA1”. Parameter name: oauth_signature_method

Timestamp – this is the number of seconds since the UNIX Epoch (1/1/1970).  This value is critical and must be calculated correctly. Always check the date and time on your Windows Phone emulator (mine was way off) if you start getting timestamp errors.  Here is my code:

        private int UnixTimestamp
        {
            get { return (int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds; }
        }

.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; }

Parameter name: oauth_timestamp

Token – this is the access token that you were given by Azure Mobile Services.  This token represents a users acceptance that your application is permitted to access their data. Parameter name: oauth_token

Version – this is a constant value of “1.0”Parameter name: oauth_version

Putting it together

To build this string you need to create a string of the format: “OAuth ”.  The actual step by step instructions can be viewed at the link I provided earlier.  However, I have always found code to be easier to understand, so here is my code generating this string:

        private string CreateAuthorizationHeaderString(string signature, string nonce, string ts)
        {
            var authString = new StringBuilder();
            authString.Append("OAuth ");
            var authParams = new Dictionary<string, string>
                    {
                        {"oauth_consumer_key", _consumerKey},
                        {"oauth_nonce", nonce},
                        {"oauth_signature", signature},
                        {"oauth_signature_method", SigMethod},
                        {"oauth_timestamp", ts
                        {"oauth_token", _accessToken},
                        {"oauth_version", Version}
                    };

            var isFirst = true;
            foreach (var kv in authParams)
            {
                if (!isFirst)
                    authString.Append(", ");

                authString.AppendFormat("{0}=\"{1}\"", WebUtility.UrlEncode(kv.Key),
                                                       WebUtility.UrlEncode(kv.Value));
                isFirst = false;
            }

            return authString.ToString();
        }

.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; }

Aside from the value of signature all of the values are accounted for and populated.  The result of this method gets added into the request as a header (as the name implies).  Here is the code for that:

AddHeader("Authorization", CreateAuthorizationHeaderString(signature, nonce, timestamp));

.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; }

The first step in creating the signature is gathering all of the parameters that will be needed.  They include:

  • A dictionary containing all of the parameter values from above, minus the signature key value pair.  Note that it should also include ANY parameters you are passing in the query string as well
  • The string representation of the method to be used for the request: ex: “GET” or “POST”
  • The full URL that will be accessed.  Do NOT include any query string information

Note: this process makes heavy use of URL encoding.  You can access these methods using the System.Net.WebUtility helper class.

The first part of the parameter string is a combination of an uppercase string representing the HTTP method being used and the percent encoded (Url encoded) request Url (with query string parameters) separated by an ‘&’.  Like this:

var sb = new StringBuilder();
sb.AppendFormat("{0}&", method.ToUpper(), WebUtility.UrlEncode(baseUrl));

.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; }

Next you will want to concatenate the authorization parameters. My recommendation is to use a LINQ query to rebuild the dictionary so that it contains ONLY percent encoded (Url encoded) values and is appropriately sorted.  Here is an example of what I did:

parameters = parameters.Select(kv => new
{
    Key = WebUtility.UrlEncode(kv.Key),
    Value = WebUtility.UrlEncode(kv.Value)
}).OrderBy(ao => ao.Key).ThenBy(ao => ao.Value)
                       .ToDictionary(ao => ao.Key, ao => ao.Value);

.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; }

Next, you will want to look through this dictionary and build it up much like a query string looks with and equal (‘=’) between the keys and values and am ampersand (&) between the actual pairs.  Here is my loop:

var isFirst = true;
foreach (var param in parameters)
{
    if (!isFirst)
        paramString.Append("&");

    paramString.AppendFormat("{0}={1}", param.Key, param.Value);
    isFirst = false;
}

.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; }

Always, remember that when doing string concatenation to utilize the System.Text.StringBuilder class to carry out the operation.  That is what I am using here with paramString.

Next, you take the entire parameter string and percent encode (Url encode) it.  So like this:

WebUtility.UrlEncode(paramString.ToString())

.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; }

Next, we have to create a signing key before we can use SHA1 to create our hash.  This is done by encoding the Consumer Secret and Access Token Secret together into a predefined string format like this:

var signingKey = new StringBuilder();
signingKey.AppendFormat("{0}", WebUtility.UrlEncode(_consumerSecret),
                        WebUtility.UrlEncode(_accessTokenSecret));

var hasher = new HMACSHA1(Encoding.UTF8.GetBytes(signingKey.ToString()));

.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; }

Doing this effectively creates your signing key which  you can use to initialize the SHA1 hash algorithm.  The next step is hash the entire parameter string that you have created thus far and then return the Base64 representation of it, this represents the oauth_signature.

The entire code for making this request is located here: https://dl.dropboxusercontent.com/u/16266819/TwitterRequest.cs

Making the Request

So at the start of this I talked about how we can use Mobile Services to authenticate ourselves and through a call on the user object inside the REST endpoint we can get all of the information needed to make authorized requests.  We then walked through the steps to creating an authorized Twitter request, so now lets make the request.

For the purposes of this I have written a couple awaitable methods so that we can take advantage of the new asynchronous programming model available in .NET 4.5.  Center to his is the Execute method within the TwitterRequest class:

public Task<string> Execute(RestClient client, string resource, Method method)
{
    var tcs = new TaskCompletionSource<string>();
    client.ExecuteAsync(this, response =>
        {
            if (response.ResponseStatus == ResponseStatus.Completed)
                tcs.SetResult(response.Content);
            else
                tcs.SetException(response.ErrorException);
        });

    return tcs.Task;
}

.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; }

Without getting too much into what is going on here, the TaskCompletionSource informs .NET that any dependencies on the return value of this method should be held until the value is ready.  We notify it is ready by calling SetResult, conversely we can inform the system of an error through SetException.  The return value of this method the Task which will hold the response string (we are retrieving JSON from this request).  I can then make the following call to get the last 20 status for the authorized user:

public async Task<IList> GetStatusUpdates()
{
    var restClient = new RestClient("https://api.twitter.com/1.1/");
    var request = new TwitterRequest("https://api.twitter.com/1.1/statuses/user_timeline.json",
                                     "statuses/user_timeline.json", Method.GET, ConsumerKey, ConsumerSecret,
                                     _accessToken, _accessTokenSecret);

    string result = await request.Execute(restClient, "user_timeline.json", Method.GET);
    var statusArray = JArray.Parse(result).AsJEnumerable();

    return statusArray.Select(jo => new StatusUpdate
    {
        Status = jo["text"].ToString(),
        Source = jo["source"].ToString(),
        UserLocation = jo["user"]["location"].ToString()
    }).ToList();
}

.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; }

Within this method we are very explicit about the importance of the result variable in finishing the method.  .NET will see this and ensure that code dependant on result is not executed until SetResult is called.  When it is, the remainder of this code should be self explanatory.  The actual call to this client looks like this:

private async void btnGetTweets_OnClick(object sender, RoutedEventArgs ev)
{
    var client = new TwitterClient(oauth_consumer_key, oauth_consumer_secret);
    client.SetAuthorization(_mobileServiceUser.AccessToken,
        _mobileServiceUser.AccessTokenSecret);

    var results = await client.GetStatusUpdates();
    lstTweets.ItemsSource = results;
}

.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; }

Simple, although I am still working to clean up the integration points between the Client and the Request, but this is workable for now.

I hope this article has helped you understand how using Azure Mobile Services can be valuable when interfacing with APIs like Facebook or Twitter.  I often find that the most difficult part of this process is the authentication and being able to get the Access Token and Access Token Secret, so to be able to use Azure Mobile Service to get in literally four lines of code is quite nice

Building an AngularJS Currency Converter

AngularJS is one of those hot new JavaScript frameworks that follows in the footsteps of Backbone to allow developers to easily write JavaScript intensive web applications.  AngularJS is gaining a lot of traction thanks to support from Google and a surplus of awesome features that enhance all aspects of JavaScript development.

I decided I would create a free currency converter using AngularJS as a way to gain familiarity with the basic concepts.  First I watched the Pluralsight course on AngularJS to gain familiarity with the core concepts.  This is not going to be a full blown intro to AngularJS, that requires a series of blog entries to do it justice.

Part 1: Laying out the application

For my layout I decided to go with Twitter Bootstrap just to make it look nice.  Screen shot below shows our interface:

image

To get AngularJS going, you need to first create a reference to the main framework library.  You can use the CDN available at http://www.angularjs.org and click on the download link.  Once you have that  you have to do some local setup.

The first thing is to register the Angular app.  Usually you create an app.js file, define the application, include it in your HTML page and then update your markup to make it aware of Angular.

app.js

'use strict';
// Declare app level module which depends on filters, and services
angular.module('currencyConvert', ['currency.controllers', 'currency.services']);

.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; }

Index.cshtml
image

There are other files here, we will cover those shortly.  Finally, you need to make your page aware that Angular is being used.  This is nothing more than the addition of the ng-app directive.

<html ng-app="currencyConvert">

.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; }

It is NOT a coincidence that the first parameter to module in app.js and the value given to ng-app is the same.  This is required to identify the Angular app in use for the web application.

The next angular concept to understand is that it enforces a strict separation of concerns.  All user interactions are handled, to start, in a controller.  I define my controllers in a controllers.js file

Each controller is then related to a block of HTML.  For example

<div ng-controller="currencyCtrl">
    <h3>Convert a Currency</h3>

    <form class="form-horizontal">
    

        <input type="button" class="btn btn-success" value="Convert" ng-click="convert()" /> 
        <input type="button" class="btn" value="Switch" ng-click="switch()" />
    </form>
</div>

.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; }

In this case, the currencyCtrl is in use here.  Note: the Ctrl suffix for controllers is a Angular convention, it is not required, but it is recommended that you stick with this convention to help other developers.  I left in a couple directive calls (both to ng-click), you can think of these as calling methods on the underlying view model, the viewmodel and controller are kind of one in the same in AngularJS.  Here is the controller definition:

'use strict';

/* Controllers */

angular.module('currency.controllers', []).
    controller('currencyCtrl', ['$scope', 'currencySvc', function ($scope, currencySvc) {
        currencySvc.getCurrencyCodes().then(function (data) {
            // ommited for brevity
        });

        $scope.convert = function () {
            // ommited for brevity
        };

        $scope.switch = function () {
            // ommited for brevity
        };
    }]);

.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; }

Perhaps, the coolest thing Angular offers is Dependency Injection, you can see it in the example above.  Without going into too much detail, $scope and currencySvc are injected into the controller and subsequently used by the methods.  I am only showing the getCurrencyCodes call.  $scope is provided by AngularJS whereas currencySvc is a custom service which I defined.

To create your own custom service, similar to the controllers, you define them using angular.module call, but calling service instead of controller.  Here is the full code for the service interacting with my Currency Converter API:

'use strict';

/* Services */

angular.module('currency.services', []).
    service('currencySvc', ['$http', '$q', function($http, $q) {
        return {
            getCurrencyCodes: function() {
                var deffered = $q.defer();
                $http({ method: 'GET', url: '/Currency/List' }).
                    success(function (data, status, headers, config) {
                        deffered.resolve(data);
                    })
                    .error(function(data, status, headers, config) {
                        deffered.reject(status);
                    });

                return deffered.promise;
            },

            convert: function(srcCode, destCode, amount) {
                var deffered = $q.defer();
                var urlPath = "/Currency/Convert?srcCode=" + srcCode + "&destCode=" + destCode + "&amount=" + amount;

                $http({ method: 'GET', url: urlPath }).
                    success(function (data, status, headers, config) {
                        deffered.resolve(data);
                    })
                    .error(function(data, status, headers, config) {
                        deffered.reject(status);
                    });

                return deffered.promise;
            }
        };
    }]);

.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; }

Understand that $q is a reference to Angular’s promise library.  If you are not aware what promises are, they are a paradigm used commonly to manage asynchronous calls.  More details are available here: http://docs.angularjs.org/api/ng.$q.  What is important to understand here is I am using the $http to contact my web service and get back JSON.  The results are then passed to the controller which then binds them to the view.

Creating the Currency Conversion API

This was actually rather difficult.  While there is a variety of Currency Conversion APIs available, finding one that was both complete and free proved challenging.  I ended up setting on Google, which actually provides an API for their calculator functionality which will return JSON.

Create the List of Currencies

I ended up having the screen scrape to get these values.  To make this task easier I added the HTML Agility Pack via nuget.  The URL to scrape was https://www.google.com/finance/converter.  You will notice that this isnt giving us a list of the currencies, instead I am scraping them out of the select list.

using (var client = new WebClient())
{
     var htmlString = client.DownloadString("https://www.google.com/finance/converter");
     var document = new HtmlDocument();
     document.LoadHtml(htmlString);

     var list = new List();
     var selectNode = document.DocumentNode.SelectSingleNode("//select");
     foreach (var optNode in selectNode.SelectNodes("option"))
     {
          list.Add(new Currency
          {
               Code = optNode.GetAttributeValue("value", string.Empty),
               Description = optNode.NextSibling.InnerText
           });
      }

      return list;
}

.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; }

Using the HTML Agility Pack, the act of screen scrapping is made much easier than it would’ve been in the past.  This returns a JSON array of objects containing a code and description.  To populate our select lists we use the ng-options and ng-modal directives in AngularJS.  For example, here is the markup for the dropdown used to select the source currency:

<select ng-model="srcCode" ng-options="item.Code as item.Description for item in codes"></select>

.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; }

One thing I will point out is that for ng-options to work, the ng-modal attribute must also be present.  As you can tell, ng-options takes a query of sorts, which defines the mapping of value to display.  In this case we are saying that item.Code is the value (the value of the value attribute on each individual option tag) and item.Description is the value the user will actually see and “select”.  The presence of ng-model binds the srcCode property so that the controller can be aware of changes to its value.

Converting Currencies

Once we have our source and destination currency codes, we can attempt to convert them.  We will once again use an API call to front our call to Google.  But first we have to understand how we make that call.  Add a button to the markup and specify the ng-click attribute like so:

<input type="button" class="btn btn-success" value="Convert" ng-click="convert()" />

.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; }

The presence of this directive tells Angular to call the convert function on the related controller, passing no parameters, when the button is clicked (this could also be a link).  Here is the definition for the convert method as it exists within the controller:

$scope.convert = function () {
     currencySvc.convert($scope.srcCode, $scope.destCode, $scope.amount).
          then(function (data) {
                $scope.sourceDisplay = data.SourceDisplay;
                $scope.destinationDisplay = data.DestinationDisplay;
            });
        };

.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; }

This is the function that will get called when the user clicks the button.  All it does is pass the selected values from the Source Currency and Destination Currency (the Code values) and an amount entered through a textbox to the service call.  This type of pattern is known as MVVM (Model View ViewModel).  In this design pattern, we use binding to mitigate having to use JavaScript to get values out of controls. Very often the way values are extracted is through selection that is inherently dependant on certain definitions within the view.  Since these element may change it makes more sense to use binding to maintain functionality even in the fact of design changes.  This is quickly becoming the backbone for modern JavaScript development and also enables cleaner separation of code and markup, essential in JavaScript intensive applications.

When the function is called, it calls a method of the same name on the currency service (the same service we called to get the list of currency codes).  This method is responsible for actually contacting the API to perform the conversion, here is the code which makes the call:

          convert: function(srcCode, destCode, amount) {
                var deffered = $q.defer();
                var urlPath = "/Currency/Convert?srcCode=" +
                      srcCode + "&destCode=" + destCode + "&amount=" + amount;

                $http({ method: 'GET', url: urlPath }).
                    success(function (data, status, headers, config) {
                        deffered.resolve(data);
                    })
                    .error(function(data, status, headers, config) {
                        deffered.reject(status);
                    });

                return deffered.promise;
            }

.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; }

This should look pretty similar to the service method above which we used to get the list of supported currency codes.  As for the code which does the conversion on the server, here it is:

public ActionResult Convert(string srcCode, string destCode, float amount)
{
     var client = new RestClient(string.Empty);
     var request = new RestRequest(
          string.Format("http://www.google.com/ig/calculator?hl=en&q={2}{0}=?{1}",
               srcCode, destCode, amount), Method.GET);

     var response = client.Execute(request);
     var content = response.Content;

     var jsonResponse = JObject.Parse(content);
     var returnObject = new ConvertResponse
     {
          SourceDisplay = jsonResponse["lhs"].ToString(),
          DestinationDisplay = jsonResponse["rhs"].ToString()
     };
}
return Json(returnObject, JsonRequestBehavior.AllowGet);

.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; }

This time we make a call to Google’s calculator API, passing the source, destination, and the amount.  We then assign what we get back from Google (in JSON format) to an object and pass it back for display on the client.  Here is the code in the controller and view which is responsible for this:

// Controller (JavaScript)
$scope.sourceDisplay = data.SourceDisplay;
$scope.destinationDisplay = data.DestinationDisplay;

// HTML
{{sourceDisplay}} = {{destinationDisplay}}

This is the really neat thing about an MVVM type pattern is simply by updating the variable.  Angular is watching variables on $scope and ensuring that any changes made in the controller are reflected in the view.  This removes a lot of the monotonous code of reading and setting values that previously mucked up our code.

For your convenience the source code is available here: https://github.com/xximjasonxx/CurrencyConverter. In addition, you can see the application in action here: http://currencycovert.azurewebsites.net/

Authenticating with Mobile Services

Let’s be honest, most people use Facebook or at least have an account, and if they dont have that chances are they have Twitter, Microsoft, or a Google account, if not more than one.  So why would you ever invest in your own authentication system? Usually the answer is something along the lines of “OAuth is hard”.  While that is true, we can turn to services like Azure Mobile Services and Parse which can take care of that aspect for us.

Understanding the Authentication Model

Generally, with third party authentication systems like Facebook, Twitter, Google, and Microsoft OAuth is used.  In OAuth, the application is given a set of unique values (the key and the secret).  Using these values the application will transmit a request for authentication to the third party. The user literally leaves your site, in most cases, and goes to Facebook or whatever.  Here they enter their credentials and grant the appropriate permissions to the app.  Once complete a callback is used which allows the application to recent the access token.  This is the token that will be passed as the application makes the desired API calls.  It identifies the application and the user to the service.  At no point does the application ever have to store the credentials used to access the service.

Unfortunately, making all of this work is difficult, those simpler with newer frameworks and approaches.  The difficulty has not slowed the adoption of this model for mobile applications and so this is why providers like Azure and Parse have worked to abstract the complexities away for developers.

The Setup

As with Push Notifications, Mobile Services allows you to store the values needed for operations to be carried out.  From the main page for your Mobile Service select Identity.

image

This page will contain four sections, one for each supported authentication mechanism, below are the links to get the values you will need)

Once you get the appropriate values added to the correct fields under the Identity section, hit Save.

One word of caution: I noticed during my testing that authentication didn’t seemed to work well right away with Facebook and Microsoft especially.  If you start to notice this, you might have to take some time and wait for things to propagate, especially if you start by creating a new app.

Tip: All of the callback URLs should point to your Azure Mobile Service Url (only Google uses a slight variation on this).

Coding

I wont lie, Microsoft has really done an awesome job of making this super easy for developers, almost too easy.  Here is the basic code for performing authentication:

   1:              try
   2:              {
   3:                  var client = new MobileServiceClient("MOBILE SERVICE URL", "APP KEY");
   4:                  var user = await client.LoginAsync(MobileServiceAuthenticationProvider.Facebook);
   5:   
   6:                  return user.UserId;
   7:              }
   8:              catch (InvalidOperationException)
   9:              {
  10:                  return string.Empty;
  11:              }

.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; }

What is happening here is a new MobileServiceClient is being created and then we are logging in.  What is important to understand here is that this is NOT hitting the Azure Mobile Service endpoints.  This is only about getting the UserId for the user based on the particular service; in other words this does not map to one of the triggers talked about earlier.  Instead, it is storing the user information inside the client reference.  This way when a request is made to one of the 4 operations, user information is available.

As you can see in this case I am specifying Facebook authentication, but by simply changing Facebook to MicrosoftAccount, Google or Twitter, I can change my authentication mechanism.

As you might expect, the first time this code is raised within the application you will be redirected, however, on subsequent calls the code passes through after checking with Mobile Services.  A good idea here may be to wrap the MobileServiceClient so that the two calls can be combined. I can see this working well especially as you can take advantage of the awaitable method concept in .NET.

Permissions

One of the great advantages to using the authentication concept in this way is you can then require users to be logged in before accessing your endpoints.  From the Mobile Service Home Screen, select Data –> –> Permissions.  This will give you a drop down for each operation with 4 operations:

image

  • Anybody with the Application Key
    • Generally this is going to be very similar to Everyone.  Never consider your Application Key a secret, it isn’t.  It is generally used to provide everyone-type access via the client interfaces, though not required.  My recommendation is to use this permission setting on tables/endpoints you only want selective users to know about, but the security of which are not overly critical to the application
  • Everyone
    • Everyone can hit this table/endpoint.  Think of this as defining a public table which may be a part of a wider public API
  • Only Authenticated Users
    • This requires the user be authenticated (what we showed above) before the endpoint will be able to process the request.  This is the ideal permission for most applications that have users or varying levels of access.
  • Only Scripts and Admins
    • Similar to the Application Key, this key (the Master Key) is designed to be secret and should be closely guarded.  Useful for Admin level roles and automated (trusted) scripts

Remember that all a “table” is in Mobile Services is an endpoint, a resource if you will.  Making requests against that resource will invoke the standard triggers.  Here is an example of the simplest insert trigger allowed:

function insert(item, user, request) {
    request.execute();
}

.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; }

Notice the parameters to this method.  item is the actual item being sent to the request, request is information about the incoming request, such as query string parameters.  In the case of an authenticated user, user will contain information about the user, notably the User Id, which can be stored to relate information back to a given user.  This is something I will expand on in a future post.

Needless to say, the user information is not passed and the table/resource requires the user to be authenticated the request will fail.

Closing

Let’s be quite honest. I do not see a legitimate reason for most applications to employ their own login system.  We are already seeing these shared login systems appear quite literally everywhere, and why not?  Most people have at least one of the 4 account types mentioned above and using this means one less username/password authentication a user has to remember and keep track of.  To be honest, there isn’t a need to even store the information coming from Facebook for simple authentication, Mobile Services can handle that, however, if you desire to get information from Facebook you will need to take additional steps.  I intend to cover that in other posts.

Access Mobile Services with iOS and Android

In my previous posts I have talked about how what Azure Mobile Services really does is provide endpoints for applications to work with.  The endpoints are represented as tables which feature four hook points: Insert, Read, Update, and Delete.  The HTTP method used for access will dictate which method gets called.  Here is the mapping:

  • Insert -> HTTP POST
  • Read -> HTTP GET
  • Update -> HTTP PATCH
  • Delete -> HTTP DELETE

While this is a very simple API it still requires an understanding of how to make network requests from within each platform and configuring those requests with the appropriate parameters.  While not overly difficulty it is very monotonous and tedious and isn’t something we should concern ourselves with.  This is where the Client Libraries for Azure Mobile Services come into play (http://www.windowsazure.com/en-us/develop/mobile/developer-tools/).  The library allows for these operations to be abstracted behind a common access paradigm allowing you to write similar code on the platforms.  I want to talk about how the iOS and Android versions work.

Working with iOS

I should point out that much of what you will see here is relevant to the Android side of things as well.  To begin, you must follow the appropriate instructions for referencing Azure Mobile Services Framework into Xcode; the instructions lay it out quite nicely.  Its really nothing more than dragging the output folder from the zip and dropping it on your Xcode project.  Pretty simple as far as Xcode project referencing goes.

– (void)loadChannels: (NSString *) token {

    MSClient *client = [MSClientclientWithApplicationURLString:@”YOUR MOBILE SERVICE URL”

                                       withApplicationKey:@”YOUR APPLICATION KEY”];

    

    NSString *customTableName = [NSString stringWithFormat:@”channels?token=%@”, token];

    MSTable *channelsTable = [client getTable:customTableName];

    

    [channelsTable readWithCompletion:^(NSArray *items, NSInteger totalCount, NSError *error) {

        NSMutableArray *channelArray = [[NSMutableArray alloc] initWithCapacity:totalCount];

        for (int i=0; i<items.count; i++) {

            NSDictionary *itemValue = ((NSDictionary *)[items objectAtIndex:i]);

            

            int channelId = [[NSString stringWithFormat:@”%@”, [itemValue objectForKey:@”Id”]] intValue];

            NSString *channelName = [NSString stringWithFormat:@”%@”, [itemValue objectForKey:@”Name”]];

            int associationId = [[NSString stringWithFormat:@”%@”, [itemValue objectForKey:@”AssocId”]] intValue];

            BOOL isRegistered = [[NSString stringWithFormat:@”%@”, [itemValue objectForKey:@”Registered”]] boolValue];

            

            Channel *channel = [[Channel alloc] initWithChannelId:channelId

                                                             Name:channelName

                                                       Registered:isRegistered

                                                    AssociationId:associationId];

            [channelArray addObject:channel];

        }

        

        [delegate channelsLoadComplete:channelArray];

    }];

}

 

So what is happening here is a Read operation. Notice that when I specify the name of the table I am using the endpoint name (‘channels’) and passing a token value.  The readWithCompletion method executes a read with an empty query (you can specify OData queries to your endpoints).  I also define a block of code which will get executed when the method returns.  As you can see, we are doing a read operation; under the covers the client is using GET to make the request.

This pattern is used throughout the iOS version of the Mobile Services client, for all other operations.  For example:

– (void)registerChannel:(NSInteger) channelId withToken:(NSString *)token {

    MSClient *client = [MSClientclientWithApplicationURLString:@”YOUR MOBILE SERVICE URL

                                             withApplicationKey:@”YOUR APPLICATION KEY];

    MSTable *clientChannels = [client getTable:@”ClientChannels”];

 

    NSMutableDictionary *channelDictionary = [[NSMutableDictionaryalloc] init];

    [channelDictionary setObject:@”0″ forKey:@”ClientType”];

    [channelDictionary setObject:token forKey:@”Token”];

    [channelDictionary setObject:[NSString stringWithFormat:@”%d”, channelId] forKey:@”ChannelId”];

    

    [clientChannels insert:channelDictionary completion:^(NSDictionary *item, NSError *error) {

        NSInteger assocId = [[NSStringstringWithFormat:@”%@”, [item objectForKey:@”AssocId”]] integerValue];

        

        [delegate registrationComplete: assocId];

    }];

}

Similar pattern in use here, although unlike the other libraries (Android, Windows 8, and Windows Phone) we specify a hash table as our JSON object rather than some sort of class based representation.  The effect is the same.  You see the completion block definition for what ail happen when the request completes.  This block is executed whether or not there is an error, so in a real application checks should be done and the appropriate response raised.  Under the hood, the PATCH HTTP method is used.  The reason for this, per Josh Twist from Microsoft, is an entire object need not be passed for the update to occur. This means, in a table with three fields the object could contain only 1 value + the id.  Only that one value would be updated, hence “patching”.

Documentation: none

Android

As I said earlier, the Mobile Services API is intentionally consistent in how it is interacted with across the supported platforms.  That said, each platforms has its own way of dealing with blocking code, that is code which would normally block the UI thread making an application appear unresponsive.  Like iOS, Android employs blocks of code as callbacks.  Here is an example of the same read operation from above using the Mobile Services client in Android:

NewImage

Apologies, I can’t seem to figure out how to paste colored source code from IntelliJ into Mars Edit, so you call get a picture.  The chief differences here are we see that the Mobile Services client allow us to specify a block of code for execution upon completion. Here we are using the GSON library’s JsonElement class to get the values from the array of JSON objects being returned from the server.  I should point out that I pass a reference to the MainActivity to this code, however, so as to ensure that only the method I used are exposed, I use an interface.

Lets look at Insert:

NewImage

Similar to the iOS example, its almost the exact same code.  It takes advantage of Java as an OO language and the supported “blocks” concept for long running methods.

Documentation: http://dl.windowsazure.com/androiddocs/

Closing

Consistency is the hallmark of code clean code.  Things that are written similarly are easier to debug because we can more easily follow code when we have an idea of how it works.  Being able to infer from other parts of the application is an essential skill in programming, consistency amplifies are ability to do that.  While you could easily implement the appropriate calls using things like NSURL in iOS or HttpClient in Java, this would cause code to be different and lead to possible complications when making changes.  Using the mobile services client library, these platforms specific details are not only handled for you, but are done so in a way that doesn’t impact the way you would normally write code for a system.

Up next: the Windows 8 and Windows Phone client libs