I want to develop an app with flutter. The app should use different pages for diffent kinds of users. There are three kinds of users: Club, Company and Fan.
The problem is, that I’m not able to get to the different pages. My application always stays on the login page. I’m new on working with flutter.
To manage the information, if a user is logged in or not, I use a StreamBuilder, that checks the auth.State:Changes().
To read the user information like the role, i use a FirebaseFirestore.instance.
Here’s my class, to manage the authorization.
class AuthManager {
final _firestoreInstance = FirebaseFirestore.instance;
Widget homePageManager = const AuthPage();
Widget manageAuth() {
return StreamBuilder<User?>(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
if (snapshot.hasData) {
_firestoreInstance
.collection('Users')
.doc(snapshot.data?.uid)
.get()
.then((DocumentSnapshot docs) {
final data = docs.data() as Map<String, dynamic>;
final role = data['role'];
if (role == 'Club') {
homePageManager = const ClubHomepage();
} else if (role == 'Company') {
homePageManager = const CompanyHomepage();
} else if (role == 'Fan') {
homePageManager = const FanHomepage();
}
});
return homePageManager;
} else {
print('test');
return const AuthPage();
}
},
);
}
signOut() {
FirebaseAuth.instance.signOut();
}
}
Here’s my method, to log in:
Future signIn() async {
showDialog(
context: context,
builder: (context) => const Center(child: CircularProgressIndicator()),
);
try {
final newUser = await _authInstance.signInWithEmailAndPassword(
email: emailController.text.trim(),
password: passwordController.text.trim(),
);
} on FirebaseAuthException catch (e) {
print(e);
Utils.showSnackBar(e.message);
}
navigatorKey.currentState!.popUntil((route) => route.isFirst);
}
If you need more information, please let me know.
Thank you!
3
Answers
Loading data from Firestore is an asynchronous operation, as it takes some time to get the data from the cloud-hosted database (or even from your local disk cache if it’s there). Instead of blocking your app while the data is being loaded, your main code continues to execute and runs
return homePageManager
before you’ve ever set that variable.The solution is to use a
FutureBuilder
to handle theget()
call that you do, and then in itsbuilder
method return the correct screen for the user’s role. There are quite a few example of how to do this, so I recommend having a look at these search resultsI’d suggest you check out the bloc examples for firebase login
https://github.com/felangel/bloc/blob/def93687228a3ef6893245e991983fdd801a3cea/examples/flutter_firebase_login/lib/app/routes/routes.dart#L6-L15
This is the best resource I’ve found
https://bloclibrary.dev/#/flutterfirebaselogintutorial