When I press back button and reopen my app it goes back to login screen but user is still logged in

Viewed 267

When I press back button and reopen my app it goes back to login screen but user is still logged in. I am using navigator.pushandremoveuntill when user signs in and my app works fine until I reopen my app then I am taken back to login page which shouldn't happen as I used navigator.pushandremoveuntill and removed all the background stack screens . can any one help me .

This is my code

  signIn() async {
    if (emailController.text.isNotEmpty &&
        passwordController.text.isNotEmpty &&
        passwordController.text.length >= 6) {
      setState(() {
        isClicked = true;
      });
      await FirebaseFunctions()
          .signIn(emailController.text, passwordController.text, context);

      if (FirebaseAuth.instance.currentUser != null) {
        Navigator.pushAndRemoveUntil(
            context,
            MaterialPageRoute(builder: (context) => const HomeScreen()),
            (route) => false);
      }
    } else {
      timerSnackbar(
          backgroundColor: Colors.red,
          buttonLabel: "",
          context: context,
          contentText: "Please Check your Credentials",
          second: 2,
          afterTimeExecute: () {});
      setState(() {
        isClicked = false;
      });
    }
  }

and this is main app


void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: FirebaseAuth.instance.currentUser != null
          ? const HomeScreen()
          : const SelectionScreen(),
      debugShowCheckedModeBanner: false,
    );
  }
}
2 Answers

The Firebase SDK automatically persists the user's credentials, and tries to restore them when the app restarts. This requires it to make a call to the server however (for example to check if the account was disabled) which takes a few moments, and during that time FirebaseAuth.instance.currentUser will be null. During that time your home: FirebaseAuth.instance.currentUser != null runs, and determines correctly that there is no user signed in yet, and renders the SelectionScreen.

The solution is to use an auth state listener, similar to what I show in this article for Android: Listen for authentication state in Android. Since this is a Stream, you can wire it up with a StreamBuilder in your widget tree, to have your UI respond to any changes in authentication state.

You should use SteamBuilder for this purpose. Just edit the code below depending on your need:

void main() async{
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Firebase',
      theme: ThemeData(
        primarySwatch: Colors.green,
      ),
      initialRoute: "/",
      routes: {
        "/": (context) => directPage(),
      },
    ),
  );
}

class directPage extends StatelessWidget {
  const directPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return StreamBuilder(
        stream: FirebaseAuth.instance.authStateChanges(),
        builder: (_,snapshot){
          if(snapshot.hasData){
            return pageOne(); //your page class you want to show when you are logged in. Like showing the welcome page
          }else{
            return pageTwo(); //your page class you want to show when you are not logged in. Like showing the login page
          }
        }
    );
  }
}
Related