I use firebase to authenticate, and to know the user current state I use authStateChanges function inside a Stream function, and it works fine but when the user is logged-in, it first goes to the login screen for a fraction of second then it goes to the user/home page .. I don't understand why it goes to the login screen first!! It doesn't stay there, but it goes there first then it opens my home page !!
Here is my code ::
Main.dart
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
home: landingpage(),
);
}
}
landingPage.dart
class landingpage extends StatelessWidget {
final Future<FirebaseApp> _initialization = Firebase.initializeApp();
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: _initialization,
builder: (context, snapshot) {
if (snapshot.hasError) {
return Scaffold(
body: Text('Error: ${snapshot.error}'),
);
}
if (snapshot.connectionState == ConnectionState.done) {
return MultiProvider(
providers: [
ChangeNotifierProvider<ModalHudState>(
create: (context) => ModalHudState(),
),
ChangeNotifierProvider<AdminMode>(
create: (context) => AdminMode(),
),
StreamProvider.value(value: Auth().user),
],
child: MaterialApp(
initialRoute: Wrapper.id,
routes: routes,
),
);
}
return Scaffold(
body: Center(
child: CircularProgressIndicator(),
),
);
});
}
}
wrapper.dart
class _WrapperState extends State<Wrapper> {
@override
void initState() {
super.initState();
Loading();
}
@override
Widget build(BuildContext context) {
final user = Provider.of<User>(context);
//return either HomePage or Login_Screen
if (user != null) {
return HomePage();
} else {
return LoginScreen();
}
}
}
Auth.dart
class Auth {
final FirebaseAuth _auth = FirebaseAuth.instance;
//Sign up method
Future SignupClass(String email, String password) async {
final UserCredential user = await _auth.createUserWithEmailAndPassword(
email: email, password: password);
return user.user;
}
//auth change stream
Stream<User> get user {
return _auth.authStateChanges();
}
//Sign in method
Future<User> SigninClass(String email, String password) async {
try {
final user = await _auth.signInWithEmailAndPassword(
email: email, password: password);
return user.user;
} catch (e) {
print(e.toString());
return null;
}
}
//Sign out
Future SignOut() async {
try {
return await _auth.signOut();
} catch (e) {
print(e.toString());
return null;
}
}
}
routes.dart
var routes = {
Wrapper.id: (context) => Wrapper(),
Loading.id: (context) => Loading(),
LoginScreen.id: (context) => LoginScreen(),
SignupScreen.id: (context) => SignupScreen(),
HomePage.id: (context) => HomePage(),
AdminPage.id: (context) => AdminPage(),
AddProduct.id: (context) => AddProduct(),
EditProduct.id: (context) => EditProduct(),
};
authStateChanges
does not emit data immediately upon launch of the app. It can take some amount of time for the Firebase Auth SDK to figure out of the current user is valid. Sometimes this involves making a network request, which can take a long time.If you want to avoid the problem you're observing, your code should show some sort of splash screen or loading indicator until the auth state indicates that there is definitely a user signed in or not.