How to check if the user is logged in, if so show other screen?

Achieved without Firebase, but by using SharedPreferences

find code at gist

here is a simple code: Main.dart

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final SharedPreferences prefs = await SharedPreferences.getInstance();
  var isLoggedIn = (prefs.getBool('isLoggedIn') == null) ? false : prefs.getBool('isLoggedIn');
  runApp(MaterialApp(
    debugShowCheckedModeBanner: false,
    home: isLoggedIn ? anotherPage() : loginPage(),
  ));
}

using flutter package: shared_preferences

DemoApp if you don't want to use SharedPreferences in Main()


I did it using Shared preferences in main.dart file. Worked fine for me.

Widget build(BuildContext context) {
return FutureBuilder(
    future: SharedPreferences.getInstance(),
    builder:
        (BuildContext context, AsyncSnapshot<SharedPreferences> prefs) {
      var x = prefs.data;
      if (prefs.hasData) {
        if (x.getBool('isloggedin')) {
          if (x.getString('type') == 'doctor') {
            return MaterialApp(home: DrHome());
          } else
            return MaterialApp(home: PtHome());
        }
      }

      return MaterialApp(home: SignIn());
    });
}

Make use of FirebaseAuth to get the current user. If the user is not logged in the value is null otherwise, the user is logged in.

// Get the firebase user
User firebaseUser = FirebaseAuth.instance.currentUser;
// Define a widget
Widget firstWidget;

// Assign widget based on availability of currentUser
if (firebaseUser != null) {
  firstWidget = Home();
} else {
  firstWidget = LoginScreen();
}

// Run the app with appropriate screen
return MaterialApp(
  debugShowCheckedModeBanner: false,
  title: 'UniClass',
  theme: ThemeData(
    primaryColor: kPrimaryColor,
    scaffoldBackgroundColor: Colors.white,
  ),
  home: firstWidget,
);

Well you can solve this kind of problem using another approach. Instead check if there is user logged inside your loginScreen class you can do this a step before and then decide if you will show the loginScreen if there is no user logged or show another screen, MainScreen I' am supposing, if the user is already logged.

I will put some snipet showing how to accomplish this. I hope it helps. But before I will explain you what is wrong in your source code.

if(FirebaseAuth.instance.currentUser() != null){
      // wrong call in wrong place!
      Navigator.of(context).pushReplacement(MaterialPageRoute(
        builder: (context) => HomeScreen()
      ));
}

Your code is broken because currentUser() is a async function and when you make the call this function is returning a incomplete Future object which is a non null object. So the navigator pushReplacement is always been called and it's crashing because the state of your widget is not ready yet.

Well as solution you can user FutureBuilder and decide which screen you will open.

int main(){
   runApp(  YourApp() )
}

class YourApp extends StatelessWidget{

    @override
    Widget build(BuildContext context){
        return FutureBuilder<FirebaseUser>(
            future: FirebaseAuth.instance.currentUser(),
            builder: (BuildContext context, AsyncSnapshot<FirebaseUser> snapshot){
                       if (snapshot.hasData){
                           FirebaseUser user = snapshot.data; // this is your user instance
                           /// is because there is user already logged
                           return MainScreen();
                        }
                         /// other way there is no user logged.
                         return LoginScreen();
             }
          );
    }
}

Using this approach you avoid your LoginScreen class to verify if there is a user logged!

As advise you can make use of snapshot.connectionState property with a switch case to implement a more refined control.