Forum Xamarin.Forms

Android app PushAsync nav not working after Xamarin.Auth oidc completes

Hello,

I have created a Xamarin.Forms app that authorizes and authenticates using our Identity Server. The whole auth process works well in both iOS and Android - in both cases I get a token and can query our API.

The Android app does not accept navigation commands and stays "stuck" on the target activity for the custom URI callback.

The android manifest has an activity entry for is4.callback and it works well:

    // The Name property here is referred to in the Activity in Android.manifest
    // https://docs.microsoft.com/en-us/xamarin/android/platform/android-manifest
    [Activity(Name = "is4.callback")]
    public class AuthCallback : Activity
    {
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);

            if (Intent?.Data?.ToString() != null)
            {
                // Convert Android.Net.Url to Uri
                var uri = new Uri(Intent?.Data?.ToString());

                // Load redirectUrl page
                AuthenticationState.Authenticator.OnPageLoading(uri);

                //this.Finish();
                //return;

            } else
            {
                // deal with it
            }

        }
    }

The OnPageLoading() method call above sends control back to OnAuthCompleted() per Xamarin.Auth as expected:

        async void OnAuthCompleted(object sender, AuthenticatorCompletedEventArgs e)
        {
            if (e.Account != null && e.Account.Properties != null)
            {
                Client.DefaultRequestHeaders.Add("Authorization", $"Bearer {e.Account.Properties["access_token"]}");

                HttpResponseMessage response = await Client.GetAsync("https://our.is4.server/connect/userinfo");
                if (response != null)
                {
                    using (HttpContent content = response.Content)
                    {
                        string responseBody = await response.Content.ReadAsStringAsync();
                        Console.WriteLine(responseBody);
                    }
                    Console.WriteLine(_logStringPre + "MainPage.OnAuthCompleted(), calling nav:");
                    await Navigation.PushAsync(new HasAuth());
                }
                else
                {
                    // deal with it
                }
            }
            else
            {
                await Navigation.PushAsync(new NoAuth());
            }
        }

However, for Android that PushAsync to the HasAuth view doesn't happen as expected - the Activity that catches the call back (is4.callback) retains the focus. The little "back" < button at the bottom of the screen on my Pixel 3 send me to the HasAuth page, where the view should be, though. That last WriteLine prior to PushAsync does fire, I think I need to close the Android activity somehow?

The use of finish() in is4.callback prevents auth from happening. return in that activity seems to have no effect at all.

What am I missing?

Thanks!

Answers

  • omortisomortis Member ✭✭

    I do see the "If CustomTabs Login Screen does not close automatically..." suggestion from the Android OS, visible over ti is4.callback activity, but it looks to me like CustomTabs closed correctly?

  • LeonLuLeonLu Member, Xamarin Team Xamurai

    You mean await Navigation.PushAsync(new HasAuth()); Is this line not navigate the HasAuth page? It still stuck the Login page? You can add a break point for this line, check the running steps.

  • omortisomortis Member ✭✭

    @LeonLu The code does work correctly - following through the code one step at a time, control does land at the HasAuth() page as designed, but the view on my Pixel does not change and stays "stuck" at the is4.callback activity.

    The is4.callback activity has a black title/nav bar, while my app has the default blue color. Does that mean that it's actually still stuck in CustomTabs?

  • omortisomortis Member ✭✭

    Actually the @EdHubbell and @ColtBauman solution mentioned here seems to have done the trick, though I am not sure why...

            protected override void OnCreate(Bundle savedInstanceState)
            {
                base.OnCreate(savedInstanceState);
    
                if (Intent?.Data?.ToString() != null)
                {
                    // Convert Android.Net.Url to Uri
                    var uri = new Uri(Intent?.Data?.ToString());
                    // Load redirectUrl page
                    AuthenticationState.Authenticator.OnPageLoading(uri);
    
                    // new code 
                    var intent = new Intent(this, typeof(MainActivity));
                    intent.SetFlags(ActivityFlags.ClearTop | ActivityFlags.SingleTop);
                    StartActivity(intent);
    
                    this.Finish();
    
                    return;
                }
    
Sign In or Register to comment.