Keep the user logged in flutter (The app has 2 different login and main, one for Client and one for Driver)

1.2k Views Asked by At

I am doing an app in flutter and I am working on the authentication part. I want to know how I can keep my user logged in after I reload the app. Now the thing is that my app has 2 kinds of users (Client and Driver). So each has its own space, like sign in and sign up and main (after logging in). This is the code that I used for logging.

class Initializer extends StatefulWidget {
// Access to this Screen
  static String id = 'initializer';

  @override
  _InitializerState createState() => _InitializerState();
}

class _InitializerState extends State<Initializer> {

  // Firebase Stuff
  final _auth = FirebaseAuth.instance;
  final FirebaseFirestore _firestore = FirebaseFirestore.instance;
  User _user;
  // To Check if There's a Driver
  bool isDriver = true;
  void getCurrentUser() async {
    try {
      final getCurrentUser = _auth.currentUser;
      if (getCurrentUser != null) {
        getUserKind();
        _user = getCurrentUser;
      }
    } catch (e) {
      print(e);
    }
  }



getUserKind() async {
    try {
      // To fetch Database for Driver
      final QuerySnapshot checkOfDriver =
          await _firestore.collection('driver').where('uid', isEqualTo: _user.uid).get().catchError((error) {
        print(error);
      });

  if (checkOfDriver.docs.isEmpty)
    setState(() {
      isDriver = false;
    });
  else
    setState(() {
      isDriver = true;
    });
} catch (e) {
  print(e);
  return null;
}
  }
  @override
  void setState(fn) {
    if (mounted) {
      super.setState(fn);
    }
  }

  @override
  void initState() {
    super.initState();
    getCurrentUser();
  }

  @override
  Widget build(BuildContext context) {
    getCurrentUser();
    SizeConfig().init(context);
    return _user == null
        ? WelcomeScreen()
        : isDriver
            ? DriverMain()
            : ClientMain();
  }
}

It's actually working but not properly, because when I reload the app while I'm logging in as a Client, the app shows me DriverMain at the beginning for one second then it switches to the right side which is ClientMain and that causes me some errors sometimes, and it's not an efficient work anyway.

So, what I should add to the code or ...

1

There are 1 best solutions below

2
On

Firebase already persists the users credentials, and restores them automatically when the app restarts.

But this is an asynchronous process, as it requires a call to the server. By the time your getCurrentUser = _auth.currentUser code runs, that asynchronous process hasn't finished yet, so you get null.

To properly respond to the auth state being restored (and other changes), you'll want to use an auth state change listener as shown in the documentation on authentication state:

FirebaseAuth.instance
  .authStateChanges()
  .listen((User? user) {
    if (user == null) {
      print('User is currently signed out!');
    } else {
      print('User is signed in!');
    }
  });

If you want to use this in your UI, you'll typically wrap it in a StreamBuilder instead of calling listen yourself.