1

In the below code while execution at line 18 calls a future function readData() and before its complete execution its move to the line 19 i.e. print statement. I want after the readData() function is called wait for the function to complete its execution and update the flag variable and then after move with further execution

import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/cupertino.dart';
import 'package:udharibook/Screens/SignInPage.dart';
import 'package:udharibook/Screens/UserProfile.dart';
import 'package:udharibook/Screens/dashboard.dart';

class AuthService  {
  bool flag = false;
  final FirebaseAuth _auth = FirebaseAuth.instance;
  final DBRef = FirebaseDatabase.instance.reference().child('Users');

    handleAuth(){
    return StreamBuilder(
      stream: FirebaseAuth.instance.onAuthStateChanged,
      builder: (BuildContext, snapshot) {
        if(snapshot.hasData) {
         readData();
          print(flag);
          if(flag ==true)
            return DashboardPage();
          else
            return UserProfile();
        }
        else {
          return SignIn();
        }
      },
    );
  }

  Future<void> readData() async {
    final FirebaseUser user = await _auth.currentUser();
    final userid = user.uid;
    DBRef.child(userid).once().then((DataSnapshot data){
      print(userid);
      if(data.value!=null)
        {
          flag =  true;
          print(data.key);
          print(data.value);
        }
      else{
        print('User not found');
        flag = false;
      }
    });
  }

  signOut(){
    FirebaseAuth.instance.signOut();
  }

  signIn(AuthCredential authCreds){
    FirebaseAuth.instance.signInWithCredential(authCreds);
  }

  signInWithOTP(smsCode,verId){
    AuthCredential authCreds = PhoneAuthProvider.getCredential(
        verificationId: verId,
        smsCode: smsCode
    );
    signIn(authCreds);
  }
}

1 Answer 1

1

Use a FutureBuilder and let your readData return true or false instead of setting a variable.

return StreamBuilder(
  stream: FirebaseAuth.instance.onAuthStateChanged,
  builder: (BuildContext, snapshot) {
    if(snapshot.hasData) {
      return FutureBuilder<String>(
        future: readData(), 
        builder: (BuildContext context, AsyncSnapshot<String> readDataSnapshot) {
          //readDataSnapshot.data will be your true/false from readData()
          if(readDataSnapshot.hasData){
            if(readDataSnapshot.data == true)
              return DashboardPage();
            else
              return UserProfile();
          } else {
            return CircularProgressIndicator(); // or something else while waiting for the future to complete.
          }
        }
      ); 
    } else {
      return SignIn();
    }    
  },
);
Future<bool> readData() async {
    final FirebaseUser user = await _auth.currentUser();
    final userid = user.uid;
    DBRef.child(userid).once().then((DataSnapshot data){
      print(userid);
      if(data.value!=null)
        {
          print(data.key);
          print(data.value);
          return true;
        }
      else{
        print('User not found');
        return false;
      }
    });
  }
Sign up to request clarification or add additional context in comments.

1 Comment

The User Screen is showing Circular Progress bar loading Its continuosly loading only. While their is data in the database.. Does it means their is no data? I think so in readData function we must also return the dafa snapshot.Correct me if i am wrong

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.