How to make streambuilder await?

5,592

you can use .then and .getIdToken for user detail in token and claims

Map<dynamic, dynamic> claims = {}; 
Auth.onAuthStateChanged.map((firebaseUser) {
  firebaseUser
      .getIdToken()
      .then((idTokenResult) => {
            if (idTokenResult.claims != null)
              {claims = idTokenResult.claims}
          })
      .catchError((e) => {print(e)});

more info about use custom claims for access control : firebase Doc

Share:
5,592
FlutterFirebase
Author by

FlutterFirebase

Updated on December 08, 2022

Comments

  • FlutterFirebase
    FlutterFirebase over 1 year

    I am build Flutter app with Firebase login but have issue with checking login status. On startup app must check if user logged in or not so it can show correct page. If logged in show homepage (different for different user role). If not, show login page.

    I am use StreamBuilder in RootPage of app for this but problem is app must first check user info with Firestore db so it know what type of user is logged in and then can route to correct page. Problem is I no find way to make StreamBuilder wait for this function to check user info before move on. So the conditionals which operate on the values returned by function are not evaluate correctly. Here is code:

        body: StreamBuilder<FirebaseUser>(
          stream: _auth.onAuthStateChanged,
          builder: (BuildContext context, snapshot) {
            if (snapshot.connectionState == ConnectionState.waiting) {
              return new SplashScreen();
            }
            if (snapshot.hasData && getUserDetailsComplete == true) {
              _getUserDetails();
    
              if (isAdmin == true) {
                return new AdminScreen();
              } else if (isAdmin == false) {
                return new HomeScreen();
              }
            } else {
              return new RootPage();
            }
          },
        ),
      );
    }
    

    You see I have make workaround for now by: 1. Return RootPage in else statement so it loop until one of conditionals is satisfied and 2. Set boolean to true when function _getUserDetails is complete and add to conditional so widget know when function is completed. But this make app startup slow and not good style.

    Anyone know better way to do?

  • FlutterFirebase
    FlutterFirebase over 5 years
    Thanks for reply! I am try this method but have issue. User can only read Firestore db if authenticate (security rule). But if user is sign out, he is not authenticate. So now my code is break because it try read Firestore without permission if user logged out. I have try place the methods which read Firestore in conditional suggested by @blaneyneil above. This should make sure the methods only run if firebaseUser is authenticate: if(_auth.onAuthStateChanged.listen((firebaseUser){ }) != null){ . But the methods are ignore this conditional and run anyway. Any thoughts?
  • jurrdb
    jurrdb over 5 years
    I'm not sure if I fully understand the problem. It seems to me that you could solve this by simply wrapping the sensitive Firebase calls inside an if-statement that checks whether the user is logged in. Am I missing the point?
  • FlutterFirebase
    FlutterFirebase over 5 years
    Thanks for reply! Actual I have solve that issue now. Your code is now work sometimes - so give correct loading indicator and then switch to correct screen when finish firebase checking. But other times the loading indicator just keeps there - no change screen. You know what issue is? If put _doSomeFirebaseChecking() function in build method this issue no longer happen. But this obvious not good solution because it keep rebuilding widget so use a lot of processing. Maybe is problem with put _doSomeFirebaseChecking() in initState()? Maybe it is not set _screen to HomeScreen()?
  • FlutterFirebase
    FlutterFirebase over 5 years
    ^Note I added Widget to return _screen in Scaffold body because otherwise 'Missing concrete implementation of State.build'. But I not think that can cause this issue.
  • jurrdb
    jurrdb over 5 years
    It might be that some else clauses aren't covered for; the loading widget is only replaced if you tell it to. But honestly, I don't think I can answer that without the code. This might be outside of the scope of your original question.