'Getx's Obx() not working within the streambuilder in flutter

I am actually trying to login the user with phoneNumber in firebase,

  • If the user is new then he should go to register screen
  • If the user is existing then he should go to home screen

Problem -> To know whether the user is already existing or he is new , signin using phoneAuth is done, When this is done the authState is invoked and without validating the checks the screen jumps to home screen..

Code Snippet to understand this better

UtilityController.dart

...
RxBool isNewUser = false.obs;
...

Phone_Auth.dart

 Future<void> signInwithPhoneNumber(
      String verificationId, String smsCode, BuildContext context) async {
    try {
      AuthCredential credential = PhoneAuthProvider.credential(
          verificationId: verificationId, smsCode: smsCode);

      UserCredential userCredential =
          await _auth.signInWithCredential(credential);
      print("I am here signing in with phone number");
      if (userCredential.additionalUserInfo?.isNewUser == true) {
        utilityController.isNewUser.value = true;
        print( "He is a new User");
      } else {
        print("Existing User");
        Fluttertoast.showToast(msg: "Existing user");
      }
      Fluttertoast.showToast(msg: "Successfully Logged In");
    } on FirebaseAuthException catch (e) {
        Fluttertoast.showToast(msg: e.toString());
    }
  }

Main.dart

home: StreamBuilder(
          stream: FirebaseAuth.instance.authStateChanges(),
          builder: (context, snapshot) {
            if (snapshot.connectionState == ConnectionState.active) {
              if (snapshot.hasData) {
                 if (utilityController.isNewUser.value == true) {
                  return RegistrationScreen();
                } else {
                  printWarning("Home Screen");
                  return HomeScreen();
                }
              }
            }
            return PhoneAuthPage();
          }),
    );

The console

...
Home Screen
I am signing in with phone Number
He is new User
...

What i want is

...
I am signing in with phone Number
He is new User
Home Screen
...

How to achieve this ?

==== My Try =====

As i realized i have to make the authStateChanges() to wait util the userType is checked.

So i created a new obs variable named isUserTypeCheckCompleted and set it to initially false.

In PhoneAuth.dart

After the user type is checked completely , i set isUserTypeCheckCompleted to true ,

UserCredential userCredential =
              await _auth.signInWithCredential(credential);
          if (userCredential.additionalUserInfo?.isNewUser == true) {
            ...
          } else {
            ...
          }
    
utilityController.isUserTypeCompleted.value = true;  <--- adding this line 
  

In Main.dart I listened for isUserTypeCompleted value

builder: (context, snapshot) {
            if (snapshot.connectionState == ConnectionState.active) {
              if (snapshot.hasData) {
                Obx((() {
                  if (utilityController.isUserTypeCompleted.value == true) {
                    if (utilityController.isNewUser.value == true) {
                      return RegistrationScreen();
                    } else {
                      return HomeScreen();
                    }
                  }
                  return Center(child: CircularProgressIndicator());
                }));
              } 

But with this Solution it doesn't return CircularProgressIndicator nor RegistrationScreen nor HomeScreen it stays in the PhoneAuthScreen,

Why is this happening ? how to handle such cases , effectively. Help would be greatly appreciated



Solution 1:[1]

If I'm right you want here like this

Home Screen -> If user is new one -> Register Page -> Home Page

Home Screen -> If user is old one -> Home Page

As per your code, you are using GetX Package here, In GetX for observable variable, we use Obx Widget for listening observable variable changes, we use like that - Obx(()=> SOMEWIDGET()) You can just make some code changes to get the desired result -

StreamBuilder(
      stream: FirebaseAuth.instance.authStateChanges(),
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return ProgressIndicator();
        }
        if (snapshot.connectionState == ConnectionState.active) {
          if (snapshot.hasData) {
    final user = snapshot.data;
    if (user != null &&
        FirebaseAuth.instance.currentUser.additionalUserInfo?.isNewUser)
             return RegistrationScreen() else return HomeScreen()
          }
        }
        return PhoneAuthPage();
      }),
);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Andronicus