2

I'm working on Xamarin.Forms app with Parse backend. I am trying to integrate Facebook Android SDK into that. What I want to do is to get the access token natively on each device, and push that access token to Parse.com. For that I need to use official facebook sdk binding for Xamarin. I use dependency injection for that. so I have IFacebookService

public interface IFacebookService
{
    Task<string> GetFacebookToken();
    void LogOut();
}

And on each platform I implement FacebookService and inject that implementation. On iOS I had no problems. On Android the problem is that even though the facebook UI is shown, I don't receive the callbacks inside my implementation of FacebookService. I think that has something to do with how Android manages callbacks as well as how Xamarin.Forms creates activities. Let me go through the code. Here is the portion of code to request login from Facebook

var callbackManager = CallbackManagerFactory.Create();
//Here I instantiate my own implementation of IFacebookCallback
//nothing fancy here, I've just implemented the required methods with Console.WriteLine();
var loginCallback = new FacebookCallback(() => _loginInProgress = false);
//Register callbackManager and my instance of loginCallback
LoginManager.Instance.RegisterCallback (callbackManager, loginCallback);
//Here is the important part. I need an activity to show the login UI
//Xamarin forms provides me with this method.
var activity = Xamarin.Forms.Forms.Context as Activity;
//I request login
LoginManager.Instance.LogInWithReadPermissions(activity, new string[] { "public_profile", "email", "user_friends" });

So, I believe the problem is within this line

var activity = Xamarin.Forms.Forms.Context as Activity;

In the debugger I see that MainActivity is returned, which is my entry point (MainLauncher = true), and where I call Xamarin Form's initialisation methods

//Setup Xamarin forms
global::Xamarin.Forms.Forms.Init(this, bundle);
LoadApplication(new FormsApp());

The initial page that is registered in FormsApp is call LoginPage. So I believe that it is loaded as a fragment inside main activity. So, perhaps I'll need to do something like this

LoginManager.Instance.LogInWithReadPermissions(LOGIN_PAGE_FRAGMENT,......);

because in facebook sdk there are separate versions for activity and fragment. I don't know exactly how to get LOGIN_PAGE_FRAGMENT, perhaps even the issue is in some other place, which I don't understand. Do you have any ideas what can cause the issue?

1 Answer 1

2

I've resolved the issue! I've found something similar here Although my approach is a little different, but the main issue was that I needed to add the implementation of OnActivityResult to the MainActivity and create CallbackManager inside the MainActivity and delegate the OnActivityResult to that CallbackManager. So in MainActivity I added this property

public ICallbackManager CallbackManager { get; private set; } 

Then I've overridden OnActivityResult like this

protected override void OnActivityResult(int requestCode, [GeneratedEnum] Result resultCode, Intent data)
{
    base.OnActivityResult(requestCode, resultCode, data);
    CallbackManager.OnActivityResult(requestCode, (int)resultCode, data);
}

Then I've replaced the previous login code with this

var loginCallback = new FacebookCallback(() => _loginInProgress = false);
var activity = Xamarin.Forms.Forms.Context as MainActivity;
LoginManager.Instance.RegisterCallback (activity.CallbackManager, loginCallback);
LoginManager.Instance.LogInWithReadPermissions(activity, new string[] { "public_profile", "email", "user_friends" });

And Everything worked! Hope this will help someone.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.