skip to Main Content

I’m making a Flutter app with Firebase and I’m still stuck on the authentication because wether I Sign in or Sign Up, it redirects me to HomePage(). In my auth_page.dart class, I have a bool showLogin which toggles between LoginPage and RegisterPage and I want to access it in my WidgetTree so that when I Sign Up, it redirects me to CreateProfilePage() instead of Home().

Here are the two classes involved :

class AuthPage extends StatefulWidget {
  AuthPage({super.key});

  static bool getShowLogin(BuildContext context) {
    final state = context.findAncestorStateOfType<_AuthPageState>();
    return state?.showLogin ?? true;
  }

  @override
  State<AuthPage> createState() => _AuthPageState();
}

final _authKey = GlobalKey<_AuthPageState>();

class _AuthPageState extends State<AuthPage> {
  // show login page initially
  bool showLogin = true;
    void toggleScreens() {
    setState(() {
      showLogin = !showLogin;
    });
  }

  @override
  Widget build(BuildContext context) {
    if (showLogin) {
      return LoginPage(showRegisterPage: toggleScreens,);
    }
    else {
      return RegisterPage(showLoginPage: toggleScreens,);
    }
  }
}

And

class WidgetTree extends StatefulWidget {
  const WidgetTree({Key? key,}) : super(key: key);

  @override
  State<StatefulWidget> createState() => _WidgetTreeState();
}

class _WidgetTreeState extends State<WidgetTree> {

  @override
  Widget build(BuildContext context) {
    bool isLogin = AuthPage.getShowLogin(context);

    return StreamBuilder(
      stream: Auth().authStateChanges,
      builder: (context, snapshot) {
        if (snapshot.hasData) {
          return isLogin ? HomePage() : CreateProfilePage();
        }
        else {
          return AuthPage();
        }
      },
    );
  }
}

I tried putting toggleScreens() directly in AuthPage like so but it simply doesn’t toggle the pages anymore

  static void toggleScreens(BuildContext context) {
    final state = _authKey.currentState;
    if (state != null) {
      state.setState(() {
        state.showLogin = !state.showLogin;
      });
    }
  }
}

I also tried using implementing getShowLogin() like this in AuthPage but it stills redirects me to HomePage() when I register :

  static bool getShowLogin() {
    final state = _authKey.currentState;
    return state?.showLogin ?? true;
  }

Thank you in advance for the help!!

2

Answers


  1. You’ll need to use some state management and save the isLogin state.

    You can go vanilla and implement one yourself, with for example, ValueNotifier or you opt with one of the many state management package solutions out there like Riverpod and Bloc, just to mention a couple.

    Of course, you can use any of one out there.

    Login or Signup to reply.
  2. In your code, you try to access the property of AuthPage from the parent widget which here is WidgetTree. I don’t think the context will send you that boolean result:

    so to achieve what you want is better to use a provider or bloc.

    here example code using the provider:

    class WidgetTree extends StatelessWidget {
      const WidgetTree({Key? key,}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        final authProvider = Provider.of<AuthProvider>(context);
    
        return StreamBuilder(
          stream: Auth().authStateChanges,
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              return authProvider.showLogin ? HomePage() : CreateProfilePage();
            }
            else {
              return AuthPage();
            }
          },
        );
      }
    }
    

    The provider:

    class AuthProvider with ChangeNotifier {
      bool _showLogin = true;
    
      bool get showLogin => _showLogin;
    
      void toggleScreens() {
        _showLogin = !_showLogin;
        notifyListeners();
      }
    }
    

    The AuthPage

    class AuthPage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Consumer<AuthProvider>(
          builder: (context, authProvider, _) {
            if (authProvider.showLogin) {
              return LoginPage(
                showRegisterPage: authProvider.toggleScreens,
              );
            } else {
              return RegisterPage(
                showLoginPage: authProvider.toggleScreens,
              );
            }
          },
        );
      }
    }
    

    by using the provider you could easily get the boolean result of the toggle screen pretty much like you want.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search