CrossGeeks / FacebookClientPlugin

Facebook Client Plugin for Xamarin iOS and Android
MIT License
106 stars 32 forks source link

Fatal: Crash on Android when cancelling login dialog #84

Closed Tommigun1980 closed 2 years ago

Tommigun1980 commented 3 years ago

Hi and thanks for a great plugin!

There is a problem on Android though -- if you start the login flow and close the FB login dialog, the app crashes with:

[MonoDroid] UNHANDLED EXCEPTION:
[MonoDroid] System.NullReferenceException: Object reference not set to an instance of an object.
[MonoDroid]   at Plugin.FacebookClient.FacebookClientManager.RequestUserData (System.Collections.Generic.Dictionary`2[TKey,TValue] fieldsDictionary) [0x0009b] in <dfbb93ebf988478da14a244e77f0c9cd>:0 
[MonoDroid]   at Plugin.FacebookClient.FacebookPendingAction`1[T].Execute () [0x0000a] in <dfbb93ebf988478da14a244e77f0c9cd>:0 
[MonoDroid]   at Plugin.FacebookClient.FacebookClientManager+<>c.<Initialize>b__62_1 () [0x0004d] in <dfbb93ebf988478da14a244e77f0c9cd>:0 
[MonoDroid]   at Plugin.FacebookClient.FacebookClientManager+FacebookCallback`1[TResult].OnCancel () [0x0000a] in <dfbb93ebf988478da14a244e77f0c9cd>:0 
[MonoDroid]   at Xamarin.Facebook.IFacebookCallbackInvoker.n_OnCancel (System.IntPtr jnienv, System.IntPtr native__this) [0x00008] in <d779dac91ffd425596b5bc3069ab871d>:0 
[MonoDroid]   at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.25(intptr,intptr)

The error happens inside the FacebookClientManager.OnActivityResult handler, as invoked from OnActivityResult in MainActivity:

protected override void OnActivityResult(int requestCode, Result resultCode, Intent intent)
{
    base.OnActivityResult(requestCode, resultCode, intent);
    FacebookClientManager.OnActivityResult(requestCode, resultCode, intent); // <-- error happens here

    ...
}

The error happens both with 3.0.7-beta and 2.2.1 stable.

Here's hoping for a fix, Thanks!

Tommigun1980 commented 3 years ago

This is probably a duplicate of https://github.com/CrossGeeks/FacebookClientPlugin/issues/63.

Considering it was reported in February and not fixed -- is this plugin maintained anymore or are we to expect it won't get fixed and should look into alternatives?

Thanks.

bebo109 commented 3 years ago

The problem lies within the method: Plugin.FacebookClient.FacebookClientManager.RequestUserData Specifically: var fbResponse = new FBEventArgs<string>(null, FacebookActionStatus.Canceled, "User cancelled facebook operation"); _onUserData.Invoke(CrossFacebookClient.Current, fbResponse); // This is a problem if you are not subscribing to the event: facebookService.OnUserData _userDataTcs?.TrySetResult(new FacebookResponse<string>(fbResponse));

If you subscribe to the event "facebookService.OnUserData", then this value will not be null, and will be invoked.

You have 1 of 2 options to fix this. 1: Simply subscribe to the event like so:

string[] fbRequestFields = { "email", "first_name", "gender", "last_name" };
            string[] fbPermisions = { "email" };
            EventHandler<FBEventArgs<string>> userDataDelegate = null;

            Models.loginDetails loginDetails;
            userDataDelegate = async (object sender, FBEventArgs<string> e) =>
            {
                if (e == null) return;

                switch (e.Status)
                {
                    case FacebookActionStatus.Completed:
                        break;
                    case FacebookActionStatus.Canceled:
                        break;
                }

                facebookService.OnUserData -= userDataDelegate;
            };

            facebookService.OnUserData += userDataDelegate;
var response = await facebookService.RequestUserDataAsync(fbRequestFields, fbPermisions);

2: Simply edit the RequestUserData method and check for the null value, and dont invoke it if it doesnt exist:

if(_onUserData != null)
                {
                    _onUserData.Invoke(CrossFacebookClient.Current, fbResponse);
                }
rdelrosario commented 2 years ago

New version released with this fix