Hello,
Initially i tried to use this library https://github.com/jsauve/OAuthTwoDemo.XForms/ but the problem was that the Library opened a WebView with mobile Facebook Login, and the user was forced to insert every time facebook username and password.
Instead with my solution my app open native facebook login page and if can't find Facebook App installed on device, it open a WebView.
Android Project Reference:
Xamarin Project Reference:
Xamarin.Forms Project:
Create Custom Button
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace MyApp.CustomControls
{
public class FacebookLoginButton : Button
{
}
}
Create Login Page (XAML)
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:customcontrols="clr-namespace:MyApp.CustomControls;assembly=MyApp"
x:Class="MyApp.LoginPage" BackgroundColor="White">
<StackLayout Orientation="Vertical" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" Padding="15">
<customcontrols:FacebookLoginButton Text="Login With Facebook" VerticalOptions="Start"
HorizontalOptions="FillAndExpand"></customcontrols:FacebookLoginButton>
</StackLayout>
</ContentPage>
Xamarin.Android Project:
Create Custom Button Renderer
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Acr.XamForms.UserDialogs;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using MyApp.CustomControls;
using MyApp.Droid.Utils;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(FacebookLoginButton), typeof(FacebookLoginButtonRenderer))]
namespace MyApp.Droid.Utils
{
public class FacebookLoginButtonRenderer : ButtonRenderer
{
public Xamarin.Forms.Button formsButton;
private readonly IUserDialogService _dialogService;
public FacebookLoginButtonRenderer()
: base()
{
this._dialogService = DependencyService.Get<IUserDialogService>();
}
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Button> e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
formsButton = e.NewElement;
}
if (this.Control != null)
{
global::Android.Widget.Button button = this.Control;
button.Click += button_Click;
}
}
void button_Click(object sender, EventArgs e)
{
var activity = this.Context as Activity;
var intent = new Intent(activity, typeof(LoginActivity));
Forms.Context.StartActivity(intent);
formsButton.Navigation.PopModalAsync();
}
}
}
Create LoginActivity
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Acr.XamForms.UserDialogs;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using MyApp.Services;
using Xamarin.Facebook;
using Xamarin.Forms;
//IMPORTANT You MUST define "app_id" in Strings.xml
[assembly: MetaData("com.facebook.sdk.ApplicationId", Value = "@string/app_id")]
namespace MyApp.Droid
{
[Activity(Label = "LoginActivity")]
public class LoginActivity : Activity, Session.IStatusCallback, Request.IGraphUserCallback
{
private readonly IUserDialogService _dialogService;
public LoginActivity()
: base()
{
this._dialogService = DependencyService.Get<IUserDialogService>();
}
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
OpenFacebookSession();
}
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
// Relay the result to our FB Session
Session.ActiveSession.OnActivityResult(this, requestCode, (int)resultCode, data);
}
public void Call(Session session, SessionState state, Java.Lang.Exception exception)
{
// Make a request for 'Me' information about the current user
if (session.IsOpened)
Request.ExecuteMeRequestAsync(session, this);
}
public async void OnCompleted(Xamarin.Facebook.Model.IGraphUser user, Response response)
{
// 'Me' request callback
if (user != null) {
string fb_id = user.Id;
string fb_email = user.InnerJSONObject.Get("email").ToString();
string fb_firstName = user.FirstName;
string fb_lastName = user.LastName;
string message = String.Format("{0} {1}. FacebookID: {2}. Email: {3}", fb_firstName, fb_lastName, fb_id, fb_email);
this._dialogService.Alert(message);
Console.WriteLine(message);
}
else
{
string message = "Problem during Facebook Login!");
this._dialogService.Alert(message);
Console.WriteLine(message);
}
OnBackPressed();
}
public void OpenFacebookSession()
{
// Ask for username and password
Xamarin.Facebook.Session.OpenRequest op = new Session.OpenRequest(this);
//op.SetLoginBehavior(SessionLoginBehavior.SsoWithFallback);
op.SetCallback(this);
List<String> permissions = new List<String>();
//permissions.Add("publish_stream");
//permissions.Add("user_likes");
permissions.Add("email");
//permissions.Add("user_birthday");
//permissions.Add("publish_actions");
//permissions.Add("share_item");
//permissions.Add("user_friends");
//permissions.Add("user_groups");
op.SetPermissions(permissions);
Session session2 = new Xamarin.Facebook.Session.Builder(this).Build();
Session.ActiveSession = session2;
session2.OpenForPublish(op);
}
}
}
That's all!
Please contact me if you have suggestion!
Esteban Lombardo
.NET Developer
Logica S.r.l.