I have the following methods to see if the user is already logged in, which in this case I did log in and the getCurrentUser()
function works because in the console it does return "USER IS NOT NULL" but the home widget is still null giving me the "EXCEPTION CAUGHT BY WIDGETS LIBRARY" saying that the home can't be null and stuff.
userAPI.dart
Future<FirebaseUser> getCurrentUser() async {
FirebaseUser user = await FirebaseAuth.instance.currentUser();
if (user != null) {
return user;
} else {
return null;
}
}
main.dart
class App extends StatelessWidget {
@override
Widget build(BuildContext context) {
Widget home;
APIs().usersAPI.getCurrentUser().then((u) {
if (u == null) {
print('USER IS NULL');
home = WelcomePage();
} else {
print('USER IS NOT NULL');
home = FeedPage();
}
});
return MaterialApp(
title: "Jedi",
debugShowCheckedModeBanner: false,
home: home,
routes: {
'/login' : (context) => new LoginPage(),
'/feed' : (context) => new FeedPage(),
},
);
}
}
You need to make the App a StatefulWidget
and call setState
when setting the home page
setState(() {
home = WelcomePage();
});
setState(() {
home = FeedPage();
});
Plus you may need to set the home page to something other than null before the API returns.
What probably would be a better pattern is to use a FutureBuilder
. This way you will be returning the correct Widget depending on the state you are in.
return MaterialApp(
title: "Jedi",
debugShowCheckedModeBanner: false,
home: FutureBuilder<FirebaseUser>(
future: APIs().usersAPI.getCurrentUser(),
builder: (BuildContext context, AsyncSnapshot<FirebaseUser> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
case ConnectionState.waiting:
return CircularProgressIndicator();
default:
if (snapshot.hasError)
return Text('Error: ${snapshot.error}');
else
if(snapshot.data == null)
return WelcomePage();
else
return FeedPage();
}
}
),
routes: {
'/login' : (context) => new LoginPage(),
'/feed' : (context) => new FeedPage(),
},
);
}
Advancing the answer given by @aqwert, you need to check for the user is not null/is null after the connection status. See below working example - this assumes autologin if user is not null.
class LandingPage extends StatelessWidget {//call this class from the main.dart
@override
Widget build(BuildContext context) {
return StreamBuilder<FirebaseUser>(
stream: FirebaseAuth.instance.onAuthStateChanged,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.active) {
FirebaseUser user = snapshot.data;//get the user status once the connection is established
if (user == null) {
//print("User is NULL::: " + user.toString());
return LoginScreen();//
}
print("User is NOT NULL::: " + user.toString());
return DefaultScreen();//home screen
} else {
return Scaffold(
body: Center(
child: CircularProgressIndicator(),//called in case all fails while waiting for connection status
),
);
}
},
);
Here is my simple solution you can try this, First we need a stateful widget and override the function initState() inside initState() we can work something look like this-
class _MyAppState extends State<MyApp> {
String initPage;
final FirebaseAuth auth=FirebaseAuth.instance;
User currentUser;
@override
void initState() {
super.initState();
try {
currentUser = auth.currentUser;
if(currentUser!=null){
initPage=Chat.id;
/*
here id is static variable which declare as a page name.
*/
}
else{
initPage=Home.id;
}
}
catch(e){
print(e);
initPage=Home.id;
}
}
@override
Widget build(BuildContext context) {
return MaterialApp(
initialRoute: initPage,
routes: {
Home.id: (context) => Home(),
Login.id: (context) => Login(),
Registration.id: (context) => Registration(),
Chat.id: (context) => Chat(),
},
);
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.