Facebook in a Windows Phone 7 App

Tweet

In the previous post “Using Windows Live ID in a Windows Phone Application” you saw how you can authenticate a user and retrieve their profile from Windows Live. Facebook also uses OAuth 2 to allow third party applications to authenticate and interact with Facebook data. In this post you’ll learn about Facebook’s implementation and how you can post status updates back to Facebook from within your Windows Phone application.

Step 1: Creating a Facebook Application

Open a web browser and go to the Facebook Developer Page. In order to create an application you’ll need to sign in with a set of Facebook credentials. Again, we recommend creating a dedicated Facebook account for managing your applications.

Click on the Apps tab, followed by the Create New App button. You’ll be prompted to enter information about the application you’re creating (Figure 1). Remember that most of this information will be seen by the user when they’re authorizing your application to access their Facebook account.

Facebook WP7 Figure 1

Figure 1

Once you click the “Continue” button you’ll be prompted to complete a captcha-style challenge, before being allocated a App ID and App Secret (Figure 2).

Facebook WP7 Figure 2

Figure 2

Step 2: Creating the Shell Windows Phone App

To illustrate the process of authenticating against Facebook we’ll use a similar application to the one we used previously to authenticate with Windows Live ID. Again we have a WebBrowser control, a Button to trigger the authentication process and two TextBlock controls to display user information.

<phone:PhoneApplicationPage x:Class="FacebookSampleApp.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone">
    <Grid>
        <StackPanel x:Name="LayoutRoot" Background="Transparent">
            <Button Content="Authenticate" Click="AuthenticateClick" />
            <TextBlock x:Name="UserNameText" />
            <TextBlock x:Name="UserIdText" />
        </StackPanel>
        <phone:WebBrowser x:Name="AuthenticationBrowser" Visibility="Collapsed"  
                                                Navigated="BrowserNavigated" IsScriptEnabled="True" />
    </Grid>
</phone:PhoneApplicationPage>

Step 3: Create the Login URL

This step involves building the correct URL to navigate the WebBrowser control to so that the user can sign into Facebook. The URL consists of a number of elements:

  • The Base url: http://www.facebook.com/dialog/oauth
  • Query String Parameters:
    • Client ID: The App ID allocated to the Facebook application you just created
    • Response Type: The type of authentication to use (we’re going to use “token”)
    • Scope: The parts of the users account the host application is requesting access to
    • Redirect URL: The URL that the browser will redirect to after authentication has been completed. In this case we’ll use the rich client return URL hosted by Facebook, http://www.facebook.com/connect/login_success.html.
    • Display: Determines how the login prompt will be styled. Use “touch” in order to get the most usable interface for a touch driven device.

The only trick to this step is making sure that all the parameters are correctly concatenated and appropriately URL encoded.

var uriParams = new Dictionary<string, string>() {
                        {"client_id", "<your_app_id>"},
                        {"response_type", "token"},
                        {"scope", "user_about_me, offline_access, publish_stream"},
                        {"redirect_uri", "http://www.facebook.com/connect/login_success.html"},
                        {"display", "touch"}
                    };

StringBuilder urlBuilder = new StringBuilder();
foreach (var current in uriParams) {
    if (urlBuilder.Length>0) {
        urlBuilder.Append("&amp;");
    }
            var encoded = HttpUtility.UrlEncode(current.Value);
            urlBuilder.AppendFormat("{0}={1}", current.Key, encoded);
}
var loginUrl= "http://www.facebook.com/dialog/oauth?" + urlBuilder.ToString();

The scope elements defined here request permission for the application to access profile information (“user_about_me”), persist the access tokent (“offline_access”) and publish status updates (“publish_stream”).

Step 4: Prompt the User to Login

To get the user to login, all you have to do is to navigate the WebBrowser control to the loginUrl you just created. In the case of the application you’ll also need to display the WebBrowser control.

AuthenticationBrowser.Navigate(new Uri(loginUrl));
AuthenticationBrowser.Visibility = Visibility.Visible;

Step 5: User Logs In and Approves the Application

The user will see a number of screens which will prompt them to enter their credentials and then grant the requested permissions to the application (Figure 3).

Facebook WP7 Figure 3

Figure 3

Step 6: Extract the Access Token

In Figure 3, the final image is the redirect URI where your application should parse the URI query string for this page and extract the access token, before hiding the WebBrowser control.

public string AccessToken { get; set; }
private void BrowserNavigated(object sender, NavigationEventArgs e) {
    if (string.IsNullOrEmpty(e.Uri.Fragment)) return;
    if (e.Uri.AbsoluteUri.Replace(e.Uri.Fragment,"")==
         "http://www.facebook.com/connect/login_success.html") {
        string text = HttpUtility.HtmlDecode(e.Uri.Fragment).TrimStart('#');
        var pairs = text.Split('&amp;');
        foreach (var pair in pairs) {
            var kvp = pair.Split('=');
            if (kvp.Length == 2) {
                if (kvp[0] == "access_token") {
                    AccessToken = kvp[1];
                    MessageBox.Show("Access granted");
                }
            }
        }

        if (string.IsNullOrEmpty(AccessToken)) {
            MessageBox.Show("Unable to authenticate");
        }

        AuthenticationBrowser.Visibility = System.Windows.Visibility.Collapsed;
    }
} 

Step 7: Accessing Content from Facebook

The Access Token that you’ve received should only be used to interact with Facebook and should not be used to uniquely identify the current user. To access user information, including a unique identifier, you should request their profile information via the Facebook graph API. Graph API requests start with the base URL of https://graph.facebook.com to which you append a path that reflects the data you are requesting. In the case of profile information you simply need to append /me to the base url. The following code illustrates making a HttpWebRequest to retrieve profile information from Facebook.

private void RequestUserProfile() {
    var profileUrl = string.Format("https://graph.facebook.com/me?access_token={0}",  
                                                           HttpUtility.UrlEncode(AccessToken));

    var request = HttpWebRequest.Create(new Uri(profileUrl));
    request.Method = "GET";
    request.BeginGetResponse(result => {
              try {
                  var resp = (result.AsyncState as HttpWebRequest).EndGetResponse(result);
                  using (var strm = resp.GetResponseStream()) {
                      var serializer = new DataContractJsonSerializer(typeof (FacebookProfile));
                      var profile = serializer.ReadObject(strm) as FacebookProfile;
                      this.Dispatcher.BeginInvoke(
                          (Action<FacebookProfile>) ((user) => {
                                                      this.UserIdText.Text = user.Id;
                                                      this.UserNameText.Text = user.Name;
                                                                                                    }), profile);
                                            }
              }
              catch (Exception ex) {
                  this.Dispatcher.BeginInvoke( () => 
                      MessageBox.Show("Unable to attain profile information"));
              }
          }, request);
}

[DataContract]
public class FacebookProfile {
    [DataMember(Name="id")]
    public string Id { get; set; }
    [DataMember(Name="name")]
    public string Name { get; set; }
}

The final output is the user’s name and ID appearing in the relevant TextBlock controls (Figure 4).

Facebook WP7 Figure 4

Figure 4

Step 8: Posting a Status Update

To request profile information you performed a GET operation against the profile path /me. In order to update the user’s status you need to POST to the status feed at /me/feed. In contrast to the GET operation, where the Access Token was passed as a URL parameter, with the POST operation all arguments are specified as form parameters in the body of the request. The following code illustrates posting a status update using a HttpWebRequest.

private void PostStatusUpdate(string status, Action<bool, Exception> callback) {
    var request = HttpWebRequest.Create("https://graph.facebook.com/me/feed");
    request.Method = "POST";
    request.ContentType = "application/x-www-form-urlencoded";
    request.BeginGetRequestStream((reqResult) => {
        using (var strm = request.EndGetRequestStream(reqResult))
        using (var writer = new StreamWriter(strm)) {
            writer.Write("access_token=" + AccessToken);
            writer.Write("&amp;message=" + HttpUtility.UrlEncode(status));
        }

        request.BeginGetResponse((result) => {
            try {
                var response = request.EndGetResponse(result);
                using (var rstrm = response.GetResponseStream()) {
                    var serializer = new DataContractJsonSerializer(typeof(FacebookPostResponse));
                    var postResponse = serializer.ReadObject(rstrm) as FacebookPostResponse;
                    callback(true, null);
                }
            }
            catch (Exception ex) {
                callback(false, ex);
            }
        }, null);
    }, null);
}

[DataContract]
public class FacebookPostResponse {
    [DataMember(Name = "id")]
    public string Id { get; set; }
}

In order to allow the user to specify their new status, let’s add a TextBox and a Button to the user interface:

<TextBox x:Name="StatusText" />
<Button Content="Post Status Update" Click="PostUpdateClick" />

The PostUpdateClick method will in turn call the PostStatusUpdate method, passing in the value of the TextBox.

private void PostUpdateClick(object sender, RoutedEventArgs e) {
    PostStatusUpdate(this.StatusText.Text, (success,ex)=> {
        this.Dispatcher.BeginInvoke(() => {
            if (success &amp;&amp; ex == null) {
                MessageBox.Show("Status updated");
            }
            else {
                MessageBox.Show("Unable to update status");
            }
        });
    });
}

In this post you’ve seen how to authenticate against Facebook and to interact with the Facebook Graph API to retrieve and update data. Facebook contains a wealth of data about the user, their friends and their social activities, most of which is accessible via the Graph API. However, a word of caution: Facebook, like other social networks, has a habit of updating their APIs and occasionally the policies for using their APIs. Make sure you develop your application to be resilient to changes and gracefully handle any exceptions that may result from changing APIs. More information is available via the Facebook Developer Portal and the Facebook Graph API documentation.

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • http://blog.prabir.me Prabir Shrestha

    You might want to check out http://facebooksdk.codeplex.com/
    it supports windows phone 7, sivlerlight 4, .net 3.5 and .net 4

  • Sruthi

    Hi,

    I need to connect to facebook through my application and that is very much similar to the example you have shown. I have tried to implement the same code but i am getting an error near the line…
    if (string.IsNullOrEmpty(e.Uri.Fragment)) return;…..its returning as the value is null….dn’t knw what went wrong. Please help me with this.

    • Nidhi

      I am also getting e.Uri.Fragment as null. Please help me in this as soon as possible

  • http://www.builttoroam.com Nick

    Prabir – The FacebookSDK is great if you only want to integrate with Facebook. If you want to do multiple providers you may be better off writing your own. I’m yet to find a single library out there that handles multiple providers in a simple and generic way.

    Sruthi – That line gets invoked a number of times some where the value is null (correctly). I’m not sure this is where your issue is. Please feel free to email me (via my blog at http://nicksnettravels.builttoroam.com) if you want to share your source code.

  • mugu

    Can you please share the source code

  • Shreyas

    I am getting the same error in same line.
    What to do next??
    i’ve no idea about it.

  • Pham Van Hung

    Can you please share the source code? Thanks you!

  • Doug Mair

    Very useful post.

    Have you looked into how to share an image from the WP7 MediaLibrary to the users Facebook (or Twitter)?

    I’m trying to avoid having the user login to Facebook and Flickr just to post an image.

    Thanks, Doug Mair

  • jsheld

    Couldn’t get this code to work for the same reasons as listed about – the line if (string.IsNullOrEmpty(e.Uri.Fragment)) return; gets invoked only once and e.Uri.Fragment is null. Not sure if this is an issue with the facebook setup or not, but it would be nice to know what’s going on. Error code from Facebook is 191.

  • dtrowell

    Ive implemented this code into my wp7 application, but whenever I update my status all that is posted is a blank status update, anyone else had this issue / know of any fix?

    Thanks

  • http://www.itmarkerz.co.in Binu Mathew

    Nick,
    All the time before updating the status, i need to Authenticate, how can i avoid that/

  • dev

    is this code will work in wp7.5 app ?

  • http://blog.carnould.com ranouf

    Thank you for your response, it was helpfull

    But there is a pb with Fb.

    When I use display=popup or wap, I have a pb “july_2012″ migration.
    If find a response there: http://www.rudyhuyn.com/blog/2012/04/09/1220/

    You have 2 choix disable migration notice on facebook developper account or set display to popup.

    But the text can’t be read! It’s too small.

    Perhaps do u know a solution to help me and other people who read your article?

    Thank u,
    Cedric

  • Nitin Shetty

    Want to implement a like button in my windows phone application can you help me in this regards.Thanks in advance.