Home > Enterprise >  Show different pages for different users in flutter and firestore (role based authentication)
Show different pages for different users in flutter and firestore (role based authentication)

Time:08-05

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!

CodePudding user response:

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 the get() call that you do, and then in its builder 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 results

CodePudding user response:

I'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

CodePudding user response:

 if(snapshot.connectionState==ConnectionState.waiting){
              return Container();
            }
 else 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();
    }
}
  • Related