UPDATE: This tutorial will no longer work. I’ve updated it (as of late July 2012) at my new blog 25 New Things as my first “new thing” .
So, you want to use Facebook to sign into something or in some way integrate Facebook with your Windows Phone 7 app. You are in luck because it is almost hilariously easy.
I’ve uploaded this tutorial as a zip file. I tried to github it, but I’m inching up on 1 hour of trying to figure out what the hell I’m doing wrong.
Download this Tutorial Project
I’ve tried to make this a full featured tutorial, so if you just want to get to the code, head down to the “Let the User Login To Facebook” section.
Get Your Facebook Key
Go to http://developers.facebook.com and log in with your Facebook account. Give them the permissions they need and go to the “Apps” tab. Click on “Create new App”
Fill in the App Display Name and the App Namespace and do the verification. Then you’ll get to a page that gives you your App ID and App Secret.
Don’t worry about anything else here… you don’t need to select anything in the “how your app integrates with Facebook” section to do this tutorial. If you’re using Facebook integration to do some basic login and simple posting, you could probably just use the Website option.
Also, click the “Graph API Explorer” on the left and keep that open. We’ll come back to that in a moment.
Add Facebook C# SDK
Download the Facebook C# SDK and extract it. Go to the “sl3-wp” folder and unblock the Facebook.dll file (right-click => Properties=>click “Unblock”)
Open up your project (for the example, I used the Visual Studio 10 “Windows Phone Databound Application” template) and right-click on “References => Add References…”. Click “Browse” and navigate to the Facebook.dll and add it to your project.
Build Facebook Login UI
We’ll do this quick here (no MVVM, no bindings) but in later versions I’ll integrate this into a more formal project.
Open your project in Blend. For this quick-and-dirty tutorial, we’ll just add another page title and another panel for the UI we want to show when the user is logged in and set the Visibility to Collapsed on those. Our visual tree should look like this.
In our loginPanel, we’re going to add a button and a WebBrowser to our panel. Set the button (containing “sign in using facebook” in the content) to the top and the WebBrowser to fill the panel. For a little flare, I’m going to add “ShowFacebookLogin” and “HideFacebookLogin” animations. My login screen now looks like this (the WebBrowser will animate in when we press the button).
When we get our data back, we’re going to tell the user it worked by showing their name and their Facebook avatar. So we’ll add a Grid with an Image and a TextBlock to display the user, along with a friendly “Hello”. (Make sure to name all these things so that we can update them from the code.)
OK… out UI is simple, but ready to roll. Now let’s do something when the user clicks the sign-in button. Go to the “Click” event and add a method like “StartFacebookLogin”.
Let the User Login to Facebook
Add “using Facebook;” to your references at the top of your MainPage.xaml.cs file. Now, add the following properties:
private FacebookClient _asyncFbClient; private string _appID = "get from your facebook app page"; private string _appSecret = "get from your facebook app page";
Now go to your StartFacebookLogin method and add the following (explained at the end).
private void StartFacebookLogin(object sender, RoutedEventArgs e) { string[] extendedPermissions = new[] { "user_about_me", "publish_stream" }; var oauth = new FacebookOAuthClient { AppId = _appID, AppSecret = _appSecret }; var parameters = new Dictionary<string, object> { {"response_type", "token"}, {"display", "touch"} }; if (extendedPermissions != null && extendedPermissions.Length > 0) { var scope = new StringBuilder(); scope.Append(string.Join(",", extendedPermissions)); parameters["scope"] = scope.ToString(); } var loginUrl = oauth.GetLoginUrl(parameters);
webBrowser.Navigated += new EventHandler<NavigationEventArgs>(CheckForAuth);
webBrowser.Navigate(loginUrl);
}
Remember how I told you to keep the Graph API open? Here is why. It has a big list of all the extendedPermissions that you can tell Facebook you want from the user. Here, we’ve asked for basic user information and the ability to publish to the user’s stream. Ask for only the permissions you need. The user can see the details of your permission request and may reject it if you ask too much.
Next, we create our OAuth client using out AppID and AppSecret and create a Dictionary of parameters communicating to Facebook the details of our request (for example, setting “display”, “touch” tells Facebook that we want the mobile interface.
We write out permission request into our parameters and then get a login url, which we will direct to our webBrowser. Here is what we will should get.
At the point Facebook walks the user through their login and, when they are done, it hands us back the access token we’ll need to get the user info and let the user make posts through our app.
This is why we attached the CheckForAuth event handler to our webBrowser. When we navigate to a new page, we’ll check to see if we got an access token using this code:
private void CheckForAuth(object sender, System.Windows.Navigation.NavigationEventArgs e) { FacebookOAuthResult result; if (FacebookOAuthResult.TryParse(e.Uri, out result)) { if (result.IsSuccess) { IsolatedStorageSettings Settings = IsolatedStorageSettings.ApplicationSettings; if(Settings.Contains("MyFacebookAccessToken")) Settings["MyFacebookAccessToken"] = result.AccessToken; else Settings.Add("MyFacebookAccessToken", result.AccessToken); Settings.Save(); _asyncFbClient = new FacebookClient(result.AccessToken); _asyncFbClient.GetCompleted += new EventHandler<FacebookApiEventArgs>(_asyncFbClient_GetCompleted); _asyncFbClient.GetAsync("/me"); } } }
If the Uri does contain a Facebook OAuth result and it is a success, we save the access token to our settings and then immediately use it to get the most basic user information.
The problem we have right now is that we have no class to structure the data that comes back. So get that all squared away.
First, right-click on “References” and select “Add Reference…”. Select “System.Runtime.Serialization”.
Next, add a class to your project (I added mine in a folder called “Models”) and name it FacebookUser.cs.
In that class, add the following code
[DataContractAttribute] public class FacebookUser { public FacebookUser() { } private string _id; [DataMember(Name = "id")] public string ID { get { return _id; } set { _id = value; } } private string _name; [DataMember(Name = "name")] public string Name { get { return _name; } set { _name = value; } } }
The sample project has a much larger (although still incomplete) version of this model. But this one will do for our purposes.
We’ll make our “GetCompleted” event handler (remember that?) look like this:
void _asyncFbClient_GetCompleted(object sender, FacebookApiEventArgs e) { FacebookUser _fbUser = e.GetResultData<FacebookUser>(); Deployment.Current.Dispatcher.BeginInvoke(() => { fbName.Text = _fbUser.Name; BitmapImage bi = new BitmapImage(new Uri("https://graph.facebook.com/" + _fbUser.ID + "/picture")); fbAvatar.Source = bi; HideFacebookLogin.Begin(); }); _asyncFbClient.GetCompleted -= _asyncFbClient_GetCompleted; }
What we’ve done here is shove our data into a FacebookUser model. Then we use BeginInvoke to bring ourselves back to the UI thread and set all the properties we want.
Finally, we start the animation that hides the login data and shows that our Facebook login was a success.
Boom!