xamlmauiapp-shell

Navigating to LoginPage/MainPage on app start


I have a pretty standard application where a user needs to either be shown a LoginPage if the user is not authenticated or a MainPage if authenticated. The MainPage is a Shell Application with a Flyout menu.

I am trying to find the 'official' way to distinguish this navigation within the app. Currently, in my AppShell.xaml.cs I am performing this work OnAppearing. This consists of using a service provider to check authentication status (DI doesn't work here, so I have to explicitly reference the Service Provider).

public AppShell()
{
    InitializeComponent();
}

protected override async void OnAppearing()
{
    base.OnAppearing();

    //need to do Authentication
    var auth = new FirebaseAuthorization();
    var authenticated = auth.IsAuthenticated();

    //if user is Authenticated, navigate to MainPage
    if(authenticated)
        await Current.GoToAsync($"//{nameof(MainPage)}");
}

In my AppShell, I have defined my Routes as follows.

  <ShellContent ContentTemplate="{DataTemplate login:LoginPage}" 
                FlyoutItemIsVisible="False" 
                Shell.FlyoutBehavior="Disabled"
                Route="LoginPage"/>

  <FlyoutItem Title="Main">
    <ShellContent ContentTemplate="{DataTemplate mainPage:MainPage}" Route="MainPage" />
  </FlyoutItem>
  <FlyoutItem Title="Students">
    <ShellContent ContentTemplate="{DataTemplate student:StudentsPage}" Route="StudentsPage" />
  </FlyoutItem>
  <FlyoutItem Title="Teachers">
      <ShellContent ContentTemplate="{DataTemplate teachers:TeachersPage}" Route="TeachersPage"/>
  </FlyoutItem>

Observations: In my AppShell, I still have to define the LoginPage even though I don't want it to appear in my Flyout, so the only way to disable it is to explicitly disable using the behavior flags. If I completely remove the LoginPage from AppShell, then I couldn't route to the LoginPage when the user signed out of the application.

I initially defined the Routes in the mauiprogram file as follows (instead of specifying Route="Login" in the AppShell:

Routing.RegisterRoute("Login", typeof(LoginPage));

I found that the TitleBar would show the back button instead of the flyout menu even though I was using Absolute Navigation to navigate to the MainPage: await Shell.Current.GoToAsync($"//{nameof(MainPage)}");

Overarching question, is my method of navigating based on authentication status done at the most optimal place (AppShell.xaml.cs)?

EDIT (clarifying question): On app startup, (1) I want to show either a Login Page or Main Page based on user authentication status. How? (2) I want to know if I need the Login page in my AppShell, (3) knowing that I need to Route to the Login page on signout.


Solution

  • I found two articles referring to AppShell in Xamarin.Forms and how to handle checking for authenticated users. The Xamarin articles are identical to a Maui solution.

    (1) https://youtu.be/ylbgWHB_gMI?si=Ywdj4BdQQjDNW47g James navigates to a login page and checks authentication using the OnAppearing method. He also mentions that this can be done either on the Login page or in AppShell (which is where I perform my check in the code posted in the question).

    (2) https://mallibone.com/post/xamarin-forms-shell-login Mark uses an intermediary loading page between when the app starts and painting either the login page or main page. This seems a little overkill, but posting here in case anyone has an opinion.

    I will continue with option (1).