Let's get started first we'll start with the Microsoft App part, start by going to https://developer.microsoft.com/en-us/dashboard/apps/overview this is where all of your applications are listed, or will be listed.
Here we're going to hit that big blue button [Create a new app]
Now here, we're going to very carefully reserve our product name, this way when we're drunk and talk about the killer app we have our brilliant name reserved (by the time this post is published i'll release the name so one lucky person can grab it).
so we are going to have to get our applications unique id and at the time of this blog post you would get it form App management->App identity
(however that will probably change within 10 minutes of me publishing my app, just know that your're looking for the Package SID, it'll look something like
S-1-15-2-2635956083-3616007119-1179820000-4100729299-1155630488-2187398330-765838093)\
with that done next we have to configure our Facebook app, i know wtf configure two apps and we still haven't written a line of code. we'll accomplish that through the facebook developer portal, you'll have to set up an account, but i'll leave that to you.
anyway navigate to https://developers.facebook.com/apps/
so guess what? Click the button [Add a New App]
now finally you're app is up and running
you have your app id:248051828941912 which is great, but now for configuring the two to work together, go to the settings section
here you'll have to add a platform
obviously pick the window app one
here's where we enter in the sid that we got from our Microsoft App we registered before. and make sure to hit the save changes button.
next hit the add product in the right hand column
Next select other
next click the Manually build login flow
This wont do anything for you, but read the resulting page https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow it'll help a lot.
Now hit the settings in the left hand panel
Finally 50 clicks later we can start our app, so go ahead and create a new visual studio project. Now I've created a blank app, in my blank app i've created a folder call Services and in that folder i created a Class called Facebook service; why i don't know, at some point that became the cool name for what was formally known as helpers and before that handlers, but that's neither here nor there. this is what i have for a solution explorer.
Now normally i'd create viewmodels, views and models folders, but this post is already way longer then i wanted it to be. Open up the FacebookService.cs class
The basics of authenticating to facebook is:
- your UWP app calls your Facebook app
- your facebook app asks for your user credentials
- if the credentials are valid it passes you back a token with a time duration it's valid for
- otherwise you get an exception when you call the facebook graph api (https://developers.facebook.com/docs/graph-api)
so let start with building a container for our token
class fbToken
{
public string Token
{
get
{
if (_expiration > DateTime.Now)
return _token;
return null;
}
}
DateTime _expiration;
string _token;
public fbToken(string
webAuthResultResponseData)
{
if (String.IsNullOrEmpty(webAuthResultResponseData))
throw new ArgumentNullException("webAuthResultResponseData", "Token not provided");
var pattern = @"#access_token=(?<accessToken>\w+)&expires_in=(?<expiresIn>\d+)";
var regexResult = Regex.Match(webAuthResultResponseData, pattern);
_token = regexResult.Groups["accessToken"].Value;
var seconds = regexResult.Groups["expiresIn"].Value;
_expiration = DateTime.Now.AddSeconds(Convert.ToInt32(seconds));
Debug.WriteLine("access_token = " + _token);
Debug.WriteLine("expires_in = " + _token);
}
}
now in the constructor we take in a parameter "webAuthResultResponseData" this is the result from when we request our token it looks something like this:
https://www.facebook.com/connect/login_success.html
#access_token=EAADhmhEmZAFgBAIHfupZBOoGQzcZCP4VY1GTQqjRFEl27F9DcqIHEJQiyRA39dAZAj3oIsF40IanUjMOJNNzhufGmGBdSTykMMIfLsEV1XROZCVpSJEaC3SprhVCDHful49uescbjs8ZB0dyiBFMph4ZCIkCvFZBAFTcbqjgfQZA4HwZDZD
&expires_in=4993
the token part needs to be accompanied with each call to the graph api and the expires in is how many more seconds the token is valid for.
next let's create our FacebookService class
class FacebookService
{
string FacebookAppId = Uri.EscapeDataString("248051828941912");
string FaceBookRedirectUrl = "https://www.facebook.com/connect/login_success.html";
string scope = "public_profile";
//https://developers.facebook.com/docs/facebook-login/permissions
string FacebookOAuthURL = $"https://www.facebook.com/dialog/oauth?" +
"client_id={0}&"+
"redirect_uri={1}&"+
"scope={2}&"+
"display=popup&"+
"response_type=token";
fbToken fbToken { get; set; }
private async Task<string> Connect()
{
string fbURL = String.Format(FacebookOAuthURL, FacebookAppId, FaceBookRedirectUrl,
scope);
Uri StartUri = new Uri(fbURL);
Uri EndUri = new Uri(FaceBookRedirectUrl);
WebAuthenticationResult WebAuthenticationResult =
await WebAuthenticationBroker.AuthenticateAsync(WebAuthenticationOptions.None, StartUri, EndUri);
switch (WebAuthenticationResult.ResponseStatus)
{
case WebAuthenticationStatus.Success:
return WebAuthenticationResult.ResponseData.ToString();
case WebAuthenticationStatus.ErrorHttp:
Debug.WriteLine("HTTP Error returned by
AuthenticateAsync() : "
+
WebAuthenticationResult.ResponseErrorDetail.ToString());
break;
case WebAuthenticationStatus.UserCancel:
Debug.WriteLine("Error returned by
AuthenticateAsync() : "
+
WebAuthenticationResult.ResponseStatus.ToString());
break;
default:
Debug.WriteLine("C'est Bizare");
break;
}
return null;
}
public async Task<string> GetUserNameAsync()
{
//Get Access
Token first
if (fbToken == null || String.IsNullOrEmpty(fbToken.Token))
fbToken = new fbToken(await
Connect());
//Request User
info.
var httpClient = new HttpClient();
string response = await
httpClient.GetStringAsync(
new Uri($"https://graph.facebook.com/me?access_token={fbToken.Token}"));
var responseValue = JsonValue.Parse(response).GetObject();
return
responseValue.GetNamedString("name");
}
}
this class has two methods
- Connect: which just gets the token and only needs to be called when we don't have a token or it's expired
- GetUserNameAsync: which just makes an http request to the facebook graph api for our user info
four fields
- FacebookAppId: which is the id of our facebook app that we created way above
- FacebookRedirectUrl: which is required by the facebook app to complete the call back, remember we set it back in the facebook application as the valid OAuth redirect URI
- Scope: which specifies what permissions we are asking for (Ie profile, friends list, birthday, etc) see for more (https://developers.facebook.com/docs/facebook-login/permissions)
- FacebookOAuthUrl: the address where we make our call to request a token
one property
- fbToken: a container for our token
while we are at it let's create a UI
<Page
x:Class="pc.FacebookApp.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:pc.FacebookApp"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
HorizontalAlignment="Center" VerticalAlignment="Center">
<StackPanel>
<Button Click="Button_Click" Content="Connect to FaceBook"/>
<TextBlock x:Name="UserName" />
</StackPanel>
</Grid>
</Page>
It should look something like
next the codebehind
not exactly rocket science and finally what happens when you connect to facebook
first you get a modal to authenticate yourself
Once that's done your app should go and get your facebook display name
And that's all she wrote.
using pc.FacebookApp.Services;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace pc.FacebookApp
{
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
FacebookService fbService = new FacebookService();
private async void Button_Click(object sender, RoutedEventArgs e)
{
UserName.Text = $"Hello {await fbService.GetUserNameAsync()}";
}
}
}
first you get a modal to authenticate yourself
Once that's done your app should go and get your facebook display name
And that's all she wrote.