This tutorial is aimed at people using the Azure App Service backend, but it will work with any Xamarin.Forms project looking to add Facebook login integration.
Setup
To start, you will need to create a Facebook app project and connect it to your Azure backend. Azure has provided excellent instructions here on how to handle this, so I'll avoid copying everything in this post.After following the Azure instructions, there are a few more steps you will need to take to prepare your project for Facebook SDK login. Go to your project page on the Facebook developer site and select 'Facebook Login' from the menu on the left. If you don't have 'Facebook Login' available, select 'Add Product' and choose 'Facebook Login'. Now click 'Quickstart' and select 'Android' as a platform. This will walk you through adding in the necessary settings for using the Facebook SDK with your Android app. Most of the items you can skip through, but there are a few important ones to be sure to fill out:
- Google Play Package Name - should be something like com.example.appname
- Class Name - add .MainActivity to your Google Play Package Name
- Key Hash - use the provided command to generate the development key hash, then copy and paste it into the given slot
PCL Project
The PCL Project will require relatively little work. We will need to create a custom button, edit the App.cs file, and create a page to place the button on.
First, add the following line to your App class in App.cs:
public static Action<string> PostSuccessFacebookAction { get; set; }
This will allow us to send the token string from the Android project to the PCL project when we have authenticated the user.
Next, create a new button called FacebookLoginButton. The class should look like this:
public class FacebookLoginButton : Button
{
}
This is actually all we will need to do with this class. Since the Facebook SDK is platform specific, we will implement the functionality of this class in each platform project as a custom renderer.
Finally, create a Page to display the Facebook button and add the following code:
FacebookLoginButton facebookButton = new FacebookLoginButton();
App.PostSuccessFacebookAction = async token =>
{
//Here you have the Facebook token
//do with it as you please!
Debug.writeline("Token = " + token );
};
The first line creates our Facebook login button; from there you can place it where ever you like in your layout.
The second portion is what handles receiving the login token from the Android project. For now it just prints the token to the console.
That's it for the PCL project!
Android Project
The Android project requires a bit more work, but it's also not terribly complicated.Install Nuget Package
The first step is to install the Xamarin.Facebook.Android nuget package. I installed version 4.11.0.1 because its dependencies matched the Android support libraries I was already using.MainActivity
The next step is to get our MainActivity setup to run the Facebook SDK.To start, add the following lines above your namespace declaration:
using Xamarin.Facebook;
[assembly: Permission(Name = Android.Manifest.Permission.Internet)]
[assembly: Permission(Name = Android.Manifest.Permission.WriteExternalStorage)]
[assembly: MetaData("com.facebook.sdk.ApplicationId", Value = "@string/app_id")]
[assembly: MetaData("com.facebook.sdk.ApplicationName", Value = "@string/app_name")]
These lines add in permissions required by the Facebook SDK and set the ApplicationId and ApplicationName variables. We will add app_id and app_name to strings.xml shortly.
Next, we need to initialize the Facebook SDK. To do so, add the following line just after "base.OnCreate(bundle);" in the OnCreate() method:
FacebookSdk.SdkInitialize(this);
Lastly, we need to set up the callback framework for the Facebook login manager.
Add this field to your MainActivity class:
public static ICallbackManager callbackManager;
Then add these lines after the "FacebookSdk.SdkInitialize(this);" line we added a little bit ago:
callbackManager = CallbackManagerFactory.Create();
Xamarin.Facebook.Login.LoginManager.Instance.RegisterCallback(callbackManager, new FacebookCallbackHandler());
And finally, add in this method to your MainActivity class:
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
callbackManager.OnActivityResult(requestCode, (int)resultCode, data);
}
FacebookCallbackHandler
You'll notice that at the end of the last section, we referenced the FacebookCallbackHandler. Now it's time to implement this class. The FacebookCallbackHandler will be responsible for handling our login callback. It must implement 3 methods, OnError, OnCancel, and OnSuccess. This will be where we use PostSuccessFacebookAction to send the token back to the PCL project.
Here's the entire FacebookCallbackHandler class:
class FacebookCallbackHandler : Java.Lang.Object, IFacebookCallback, IDisposable
{
public void OnCancel()
{
}
public void OnError(FacebookException p0)
{
}
public void OnSuccess(Java.Lang.Object p0)
{
LoginResult loginResult = (LoginResult)p0;
App.PostSuccessFacebookAction(loginResult.AccessToken.Token);
}
}
FacebookLoginButtonRenderer
The FacebookLoginButtonRenderer will do all of the heavy lifting for us. Luckily, it's still a pretty simple class. Pretty much all we do is extend the LoginButton renderer from the Facebook libraries, and then register our callback.
To begin, add in the following line above the namespace declaration so that the Xamarin system can recognize it as a custom renderer for the FacebookLoginButton class:
[assembly: ExportRenderer(typeof(FacebookLoginButton), typeof(FacebookLoginButtonRenderer))]
[assembly: ExportRenderer(typeof(FacebookLoginButton), typeof(FacebookLoginButtonRenderer))]
Next, add in the body of the class:
class FacebookLoginButtonRenderer : ViewRenderer<Xamarin.Forms.Button, LoginButton>
{
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Button> e)
{
base.OnElementChanged(e);
Activity _activity = this.Context as MainActivity;
var loginButton = new LoginButton(this.Context);
var facebookCallback = new FacebookCallbackHandler();
loginButton.RegisterCallback(MainActivity.callbackManager, facebookCallback);
base.SetNativeControl(loginButton);
}
}
Properties/AndroidManifest.xml
The Facebook SDK requires you to register a FacebookActivity in your AndroidManifest.xml file. This Activity is provided by the SDK already, so you just have to add the following lines in between the application tags:
<activity android:name="com.facebook.FacebookActivity"
android:configChanges= "keyboard|keyboardHidden|screenLayout|screenSize|orientation"
android:theme="@android:style/Theme.Translucent.NoTitleBar"
android:theme="@android:style/Theme.Translucent.NoTitleBar"
android:label="@string/app_name" />
If the Facebook app isn't installed on the device, the Facebook SDK will open a web browser to complete login. The following portion of code is optional; it allows the Facebook SDK to use the credentials of the user if they have logged onto Facebook via Chrome, rather than making the user retype their information. It also goes between the application tags in the manifest file:
<activity
android:name="com.facebook.CustomTabActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="@string/fb_login_protocol_scheme" />
</intent-filter>
</activity>
Resources/values/strings.xml
Go ahead and create this file if it doesn't exist already. It should look like this:
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<string name="app_id">**Your App ID**</string>
<string name="app_name">**Your App Name**</string>
<string name="fb_login_protocol_scheme">fb1528045527236083</string>
</resources>
Conclusion
And there you have it! You should now have a Facebook login button that lets you authenticate via the Facebook app!