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.