4

I know this question has been asked a lot and I have spent a lot of time reading and trying to implement the answers. So I am trying to get the response from isEmailVerified from Firebase Auth to work and it does work but right now it always returns false unless I refresh the app or close it and reopen it. which is obviously a bad user experience. How do I get the response to update without having to close the app.

here is the relevant pieces of code.

 Future<bool> isEmailVerified() async {
    FirebaseUser user = await _auth.currentUser();

    if (user == null) {
      return false;
    } else {
     await user.reload();
     user = await _auth.currentUser();
      return user.isEmailVerified;
    }
  }

main.dart

  child: Consumer<Auth>(
        builder: (_, auth, __) => MaterialApp(
          theme: Provider.of<ThemeNotifier>(context).getTheme(),
          home: FutureBuilder(
            future: Future.wait([auth.isEmailVerified(), auth.tryAutoLogin()]),
            builder: (BuildContext ctx, AsyncSnapshot authResultSnapshot) =>
                authResultSnapshot.connectionState == ConnectionState.done
                    ? authResultSnapshot.data[1]
                        ? authResultSnapshot.data[0]
                            ? HearingsScreen()
                            : SplashScreen(
                                emailVerified: true,
                              )
                        : LoginScreen()
                    : SplashScreen(),
          ),

It is not returning true until I restart the app
Things I have tried besides this:
1) await user.getIdToken(refresh: true);
2) sign user out then back in
3) firebase_user_stream package

Any help is appreciated.

7
  • try adding notifylistener() in isEmailVerified() thats my guess Commented Apr 4, 2020 at 12:46
  • notifyListener() get stuck in ConnectionState.waiting in my FutureBuilder Commented Apr 4, 2020 at 16:13
  • u cannot generally use future builder and provider Commented Apr 4, 2020 at 17:56
  • try this by author itself stackoverflow.com/questions/56359049/… Commented Apr 4, 2020 at 17:57
  • I obviously did not know that ill check it out thx Commented Apr 4, 2020 at 19:05

1 Answer 1

6

I have implemented the same scenario in a splash screen with below code, you can change it as per your requirement. :

//To check is User is logged in
  Future<bool> isLoggedIn() async {
    FirebaseUser user = await _fireBaseAuth.currentUser();
    if (user == null) {
      return false;
    }
    return user.isEmailVerified;
  }

and

countDownTime() async {
    return Timer(
      Duration(seconds: splashDuration),
      () async {
        if (await userAuth.isLoggedIn()) {
            Navigator.pushReplacement(
              context,
              ScaleRoute(
                widget: HomeScreen(),),
            );
          }
        } else {
          Navigator.pushReplacement(
            context,
            ScaleRoute(
              widget: LoginScreen(),),
          );
        }
      },
    );
  }

and

  @override
  void initState() {
    super.initState();
    countDownTime();
  }

Update
One needs to implement isEmailVerified in initState() function periodically which can be the ideal approach to execute the verification with firebase.

bool _isUserEmailVerified;
Timer _timer;

@override
void initState() {
    super.initState();
    // ... any code here ...
    Future(() async {
        _timer = Timer.periodic(Duration(seconds: 10), (timer) async {
            await FirebaseAuth.instance.currentUser()..reload();
            var user = await FirebaseAuth.instance.currentUser();
            if (user.isEmailVerified) {
                setState((){
                    _isUserEmailVerified = user.isEmailVerified;
                });
                timer.cancel();
            }
        });
    });
}

@override
void dispose() {
    super.dispose();
    if (_timer != null) {
        _timer.cancel();
    }
}
Sign up to request clarification or add additional context in comments.

8 Comments

Do you do an email verification in your app this is the step I am having trouble with in your example all your checking is if the user is not null which does not guarantee isEmailVerified equals true
you can access by "user.isEmailVerified".
I guess you do not need to create new user instance in else part. The same instance defined before is sufficient to know "user.isEmailVerified".
yes I have actually implemented code very similar to this in my app but user.isEmailVerified always returns false until I close the app and restart it.
|

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.