ExtremeSwat
ExtremeSwat

Reputation: 824

Xamarin.Auth is re-initializing the app

I only encounter this issue on UWP

 private void Button_OnClicked(object sender, EventArgs e)
        {
            var clientId = Constants.GoogleUWPClientID;
            var clientSecret = Constants.GoogleUWPClientSecret;
            var redirectUrl = Constants.GoogleUWPRedirectUrl;

            var auth =  new OAuth2Authenticator(
                clientId: clientId,
                clientSecret: clientSecret,
                scope: Constants.GoogleScope,
                authorizeUrl: new Uri(Constants.GoogleAuthorizeUrl),
                accessTokenUrl: new Uri(Constants.GoogleAccessTokenUrl),
                redirectUrl: new Uri(redirectUrl),
                getUsernameAsync: null,
                isUsingNativeUI: true
            );

            // Login Events
            auth.Completed += AuthOnCompleted;
            auth.Error += AuthOnError;
            auth.IsLoadableRedirectUri = true;


            AuthenticationState.Authenticator = auth;

            var presenter = new Xamarin.Auth.Presenters.OAuthLoginPresenter();
            presenter.Login(auth);
        }

I did initialize the Xamarin.Auth on UWP

Xamarin.Forms.Forms.Init(e);
global::Xamarin.Auth.Presenters.UWP.AuthenticationConfiguration.Init();

This is the CompletedEvent handler

private async void AuthOnCompleted(object sender, AuthenticatorCompletedEventArgs authenticatorCompletedEventArgs)
        {
            //var auth = sender as Xamarin.Auth.OAuth2Authenticator;
            //auth.DoNotEscapeScope = true;

            // We presented the UI, so it's up to us to dimiss it on iOS.
            //DismissViewController(true, null);

            if (authenticatorCompletedEventArgs.IsAuthenticated)
            {
                var request = new OAuth2Request("GET", new Uri(Constants.GoogleUserInfoUrl), null, authenticatorCompletedEventArgs.Account);
                var response = await request.GetResponseAsync();

                if (response != null)
                {
                    var userJson = response.GetResponseText();
                    var user = JsonConvert.DeserializeObject<GoogleUser>(userJson);

                    //UserPicture = user.Picture;
                    //GivenName = user.GivenName;
                    //Email = user.Email;
                }
            }
            else
            {
                // The user cancelled
                //ErrorMessage = "Cancelled authentication !";
            }

        }

Once I successfully log in the AuthOnCompleted gets started with success but as soon as it ends (or encounters an await GetResponseAsync from one of my requests to Google's API) it completely refreshes the app.

My guess is that this happens due to the fact that I haven't treated the redirect-url as I did in Android and iOS ?

On the official documentation there is nothing mentioning about UWP so I'm not sure if I miss something

As soon as I hit the await enter image description here

THE App's status gets "restarted/refreshed" !? enter image description here

I am really clueless, am I missing something ?

EDIT 01 I've found out a fix but I do fear that it might have consequences. I did use NavigationCacheMode="Enabled" instead of it's default, 'Cancel'.

This will basically keep a cached version of the instance once I leave it's context and go to another ContentPage/Page/Frame. Because navigation in UWP doesn't happen like in Xamarin, you have to specify frame.Navigate(typeof(targetPage),args) so you'll prolly have to handle the cache for each page (I guess)

What worries me is that the MainPage and by using this setting from UWP and when the LoadApplication(new SharedProj.App()) this setting will be inherited somewhat by any subsequent ContentPages which might cause issues with the app performance ?

Going to do some tests to check my supposition

<forms:WindowsPage
    x:Class="AnonymousCheckerApp.UWP.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:forms="using:Xamarin.Forms.Platform.UWP"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:AnonymousCheckerApp.UWP"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
    NavigationCacheMode="Enabled"
    >

Upvotes: 0

Views: 399

Answers (1)

Nico Zhu
Nico Zhu

Reputation: 32775

I have tested your code and reproduced the "issue". It is normal behavior that the app will refresh after auth completed. Because the login page takes replace of current content page when the login page displayed.

public void Login(Authenticator authenticator)
{
    authenticator.Completed += AuthenticatorCompleted;

    System.Type page_type = authenticator.GetUI();

    Windows.UI.Xaml.Controls.Frame root_frame = null;
    root_frame = Windows.UI.Xaml.Window.Current.Content as Windows.UI.Xaml.Controls.Frame;
    root_frame.Navigate(page_type, authenticator);

    return;
}

And when AuthOnCompleted the portable library will be reloaded.

public MainPage()
{
    this.InitializeComponent();

    LoadApplication(new XamarinAuthTest.App());
}

So the app will be "restarted/refreshed".

EDIT 01

The app will not restart after auth has been completed if the NavigationCacheMode="Enabled". Because the constructor method of MainPage will not be executed in cache mode. If your application can accept the page cached design pattern. You don't need to worry about app performance.

Upvotes: 2

Related Questions