1

I've tried and tried solutions I find online and none have worked so far.

I have a Xamarin app with a LogInPage and a LoggedInPage. On start I navigate to the LogInPage, hosted within a TabBar, so the FlyoutMenu is not visible, and when the user logs in correctly I try to move the Shell to the LoggedInPage, which is part of a FlyoutMenu.

However, the app crashes and it returns the following response:

Android.Content.Res.Resources+NotFoundException Message=Unable to find resource ID #0xffffffff

My code is as follows:

App

<Application xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="FinalProject.App">
    <Application.Resources>
        <ResourceDictionary>
            <Style TargetType="Button">
                <Setter Property="TextColor" Value="White"></Setter>
                <Setter Property="VisualStateManager.VisualStateGroups">
                    <VisualStateGroupList>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal">
                                <VisualState.Setters>
                                    <Setter Property="BackgroundColor" Value="DodgerBlue" />
                                </VisualState.Setters>
                            </VisualState>
                            <VisualState x:Name="Disabled">
                                <VisualState.Setters>
                                    <Setter Property="BackgroundColor" Value="Transparent" />
                                </VisualState.Setters>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateGroupList>
                </Setter>
            </Style>
        </ResourceDictionary>
    </Application.Resources>
</Application>

AppShell

<Shell x:Name="MainShell" xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="FinalProject.AppShell"
             Title="FinalProject"
             xmlns:core="clr-namespace:FinalProject"
             xmlns:coreviews="clr-namespace:FinalProject.Views">

    <Shell.Resources>
        <ResourceDictionary>
            <Style x:Key="BaseStyle" TargetType="Element">
                <Setter Property="Shell.BackgroundColor" Value="DodgerBlue" />
                <Setter Property="Shell.ForegroundColor" Value="White" />
                <Setter Property="Shell.TitleColor" Value="White" />
                <Setter Property="Shell.DisabledColor" Value="Transparent" />
                <Setter Property="Shell.UnselectedColor" Value="Transparent" />
                <Setter Property="Shell.TabBarBackgroundColor" Value="DodgerBlue" />
                <Setter Property="Shell.TabBarForegroundColor" Value="White"/>
                <Setter Property="Shell.TabBarUnselectedColor" Value="Transparent"/>
                <Setter Property="Shell.TabBarTitleColor" Value="White"/>
            </Style>
            <Style TargetType="TabBar" BasedOn="{StaticResource BaseStyle}" />
            <Style TargetType="FlyoutItem" BasedOn="{StaticResource BaseStyle}" />

            
            <Style Class="FlyoutItemLabelStyle" TargetType="Label">
                <Setter Property="TextColor" Value="White"></Setter>
            </Style>
            <Style Class="FlyoutItemLayoutStyle" TargetType="Layout" ApplyToDerivedTypes="True">
                <Setter Property="VisualStateManager.VisualStateGroups">
                    <VisualStateGroupList>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal">
                                <VisualState.Setters>
                                    <Setter Property="BackgroundColor" Value="{x:OnPlatform UWP=Transparent, iOS=White}" />
                                    <Setter TargetName="FlyoutItemLabel" Property="Label.TextColor" Value="DodgerBlue" />
                                </VisualState.Setters>
                            </VisualState>
                            <VisualState x:Name="Selected">
                                <VisualState.Setters>
                                    <Setter Property="BackgroundColor" Value="DodgerBlue" />
                                </VisualState.Setters>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateGroupList>
                </Setter>
            </Style>

            
            <Style Class="MenuItemLayoutStyle" TargetType="Layout" ApplyToDerivedTypes="True">
                <Setter Property="VisualStateManager.VisualStateGroups">
                    <VisualStateGroupList>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal">
                                <VisualState.Setters>
                                    <Setter TargetName="FlyoutItemLabel" Property="Label.TextColor" Value="DodgerBlue" />
                                </VisualState.Setters>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateGroupList>
                </Setter>
            </Style>
        </ResourceDictionary>
    </Shell.Resources>

    <FlyoutItem Title="Main">
        <ShellContent Route="LoggedPage" ContentTemplate="{DataTemplate coreviews:LoggedPage}" />
    </FlyoutItem>
    <FlyoutItem Title="Trial">
        <ShellContent Route="TrialPage" ContentTemplate="{DataTemplate coreviews:TrialPage}" />
    </FlyoutItem>

   
    <MenuItem Text="Logout" StyleClass="MenuItemLayoutStyle" Clicked="Logout">
    </MenuItem>

    
    <TabBar>
        <ShellContent Route="LoginPage" ContentTemplate="{DataTemplate coreviews:LogInPage}" />
    </TabBar>

LogInPage.xaml:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="FinalProject.Views.LogInPage"
             BackgroundColor="White">
    <ContentPage.Content>
        <StackLayout 
        VerticalOptions="Center"
        Margin="20">
            
            <Label
                Text="Caminante"
                HorizontalOptions="Center"
                TextColor="Black"
                FontSize="35"
                Margin="0, 20"
            />

            <Entry
                Placeholder="E-mail"
                PlaceholderColor="Black"
                TextColor="Black"
                Keyboard="Email"
                x:Name="EmailInput"
            />

            <Entry
                Placeholder="Password"
                PlaceholderColor="Black"
                TextColor="Black"
                IsPassword="true"
                x:Name="PasswordInput"
            />

            <Button
                Text="Enter"
                Clicked="LoginClicked"
                Margin="60, 40"
                BackgroundColor="DodgerBlue"
                TextColor="White"
            />

            <Button
                Text="Register"
                Clicked="RegisterClicked"
                Margin="60, 40"
                BackgroundColor="DodgerBlue"
                TextColor="White"
            />

        </StackLayout>
    </ContentPage.Content>
</ContentPage>

LogInPage.xaml.cs

using FinalProject.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace FinalProject.Views
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class LogInPage : ContentPage
    {
        IAuth auth;

        public LogInPage()
        {
            InitializeComponent();

            auth = DependencyService.Get<IAuth>();

            //Routing
        }

        async void LoginClicked(object sender, EventArgs e)
        {
            string Token = await auth.LoginWithEmailPassword(EmailInput.Text, PasswordInput.Text);
            
            if (Token != "")
            {
                Storage.uid = Token;
                Storage.userEmail = EmailInput.Text;
                await Shell.Current.GoToAsync("///LoggedPage");
                //Application.Current.MainPage = new AppShell();
            }
            else
            {
                ShowError();
            }
        }

        async void RegisterClicked(object sender, EventArgs e)
        {
            await auth.RegisterWithEmailPassword(EmailInput.Text, PasswordInput.Text);
            string Token = await auth.LoginWithEmailPassword(EmailInput.Text, PasswordInput.Text);
            await FireBaseActions.AddUser(Token, EmailInput.Text);

            LoginClicked(sender, e);
        }


        async private void ShowError()
        {
            await DisplayAlert("Authentication Failed", "E-mail or password are incorrect. Try again!", "OK");
        }
    }
}

LoggedPage.xaml

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="FinalProject.Views.LoggedPage">
    <ContentPage.Content>
        <StackLayout x:Name="slLoggedIn1">
            <Label Text="Working?"/>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

LoggedPage.xaml.cs

namespace FinalProject.Views
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class LoggedPage : ContentPage
    {
        public string noChars { get; set; }
        public List<Character> lista { get; set; }
        public bool Visible { get; set; }
        public bool notVisible { get { return !Visible; } }
        public LoggedPage()
        {
            BindingContext = this;
            noChars = "Hello, " + Services.Storage.userEmail + "!" + Environment.NewLine + "It seems you don't have any characters yet, press the button below to fix that.";
            if (FireBaseActions.GetUserCharacters().Result.Count.Equals(0) || FireBaseActions.GetUserCharacters().Result.Equals(null))
            {
                lista = new List<Character>();
                Visible = false;
            }
            else
            {
                lista = FireBaseActions.GetUserCharacters().Result;
                Visible = true;
            }

            InitializeComponent();
        }

Edit: Added IAuth by a commenter's suggestion.

IAuth implementing class:

[assembly: Dependency(typeof(AuthDroid))]
namespace CaminanteFinal.Droid
{
    class AuthDroid : IAuth
    {
        public async Task<string> LoginWithEmailPassword(string email, string password)
        {
            try
            {
                var user = await FirebaseAuth.Instance.SignInWithEmailAndPasswordAsync(email, password);
                var token = await (FirebaseAuth.Instance.CurrentUser.GetIdToken(false).AsAsync<GetTokenResult>());
                //return FirebaseAuth.Instance.CurrentUser.Uid;
                return token.Token;
            }
            catch (FirebaseAuthInvalidUserException e)
            {
                Acr.UserDialogs.UserDialogs.Instance.Alert(e.ErrorCode, "Error", "Ok");
                e.PrintStackTrace();
                return "";
            }
            catch (FirebaseAuthInvalidCredentialsException e)
            {
                Acr.UserDialogs.UserDialogs.Instance.Alert(e.ErrorCode, "Error", "Ok");
                e.PrintStackTrace();
                return "";
            }
        }
        public async Task<string> RegisterWithEmailPassword(string email, string password)
        {
            try
            {
                var user = await FirebaseAuth.Instance.CreateUserWithEmailAndPasswordAsync(email, password);
                Acr.UserDialogs.UserDialogs.Instance.Alert("User " + email + " with password " + password + " has been created.", "Success!", "Ok");
                return "";
            }
            catch (FirebaseAuthUserCollisionException e)
            {
                Acr.UserDialogs.UserDialogs.Instance.Alert(e.ErrorCode, "Error", "Ok");
                e.PrintStackTrace();
                return "";
            }
            catch (FirebaseAuthWeakPasswordException e)
            {
                Acr.UserDialogs.UserDialogs.Instance.Alert(e.ErrorCode, "Error", "Ok");
                e.PrintStackTrace();
                return "";
            }
            catch (FirebaseAuthInvalidCredentialsException e)
            {
                Acr.UserDialogs.UserDialogs.Instance.Alert(e.ErrorCode, "Error", "Ok");
                e.PrintStackTrace();
                return "";
            }
        }
    }
}
  • 1
    Are you using a platform specific thing coupled to LoggedPAge like a custom renderer for instance ? the error you mentionned seems to be a platform specific error and doesn't have a direct link with the shared code (Xamarin.Forms) you shared in the question. – Cfun Jun 03 '21 at 23:54
  • Could you put breakpoint at `await Shell.Current.GoToAsync("///LoggedPage");` and confirm that after this line the exception you mentioned is being thrown? – Cfun Jun 03 '21 at 23:56
  • How about commenting out the styles of `TabBar` and `FlyoutItem` in AppShell? – Shaw Jun 04 '21 at 01:22
  • @Cfun Thanks for answering. As for your first comment, not that I know of! This is just a proof of concept in how to store and retrieve user-specific data from Firebase. As for your second, `await Shell.Current.GoToAsync("///LoggedPage");` works just fine, no matter what page I put there. Is the second GoToAsync, the one that happens after I click the Login button, that crashes the app immediately. In fact, any movement inside the FlyoutMenu is the reason it all crashes. – Fernando Sánchez Jun 04 '21 at 05:54
  • @Shaw Commenting every style still crashes the app. Thank you for your time, tho! – Fernando Sánchez Jun 04 '21 at 06:03
  • Could you show the class which implement the `IAuth` interface in android project (which you call `DependencyService.Get();`)? – Leo Zhu Jun 04 '21 at 06:11
  • @LeoZhu-MSFT added to the post! – Fernando Sánchez Jun 04 '21 at 06:21
  • @FernandoSánchez It doesn't seem to be the issue with the class. Does it throw the exception when you open the LoggedPage?Try to move `InitializeComponent();` to the first row of the constructor – Leo Zhu Jun 04 '21 at 06:34
  • @LeoZhu-MSFT Doesn't seem to work, I've left only the InitializeComponent(); and a single Label on LoggedPage, still crashes. LoggedPage doesn't even need to be invoked, even, any movement on the Flyout crashes the app with the same command. – Fernando Sánchez Jun 04 '21 at 06:55
  • I recommend starting a new app. Start without any of your custom code, make sure the empty AppShell works. Then add a simple flyout. See if you can get that much working, before adding any custom code, or plug-ins. Then gradually add in the features you use, and your custom code, testing at each step. – ToolmakerSteve Jun 04 '21 at 09:09
  • @FernandoSánchez i don't see a second GoToAsync, do you mean `Application.Current.MainPage = new AppShell();` ? – Cfun Jun 04 '21 at 10:11
  • It seems you are create a first instance of AppShell initially and after logging in you try to create another one which I don't find it a good design, check [my answer in this post](https://stackoverflow.com/a/65187674/5228202) i think it might be helpful for your case – Cfun Jun 04 '21 at 10:22

1 Answers1

1

This is an issue with Xamarin.Forms, which is already tracked on github.

You need to wait for next SR for XF5 when this PR is merged or rollback to XF 4.8

magicandre1981
  • 27,895
  • 5
  • 86
  • 127
  • 1
    Might be a workaround: https://github.com/xamarin/Xamarin.Forms/issues/13843#issuecomment-819742029 – Shaw Jun 05 '21 at 11:17