Flutter: How to listen to the FirebaseUser is Email verified boolean?

eifachtimon picture eifachtimon · Jul 25, 2019 · Viewed 9.8k times · Source

My Idea: I want to use the Firebase Auth Plugin in Flutter to register the users. But before they can access the App, they have to verify their Email address. Therefor I push the Firebase users after registration to a verification screen. This is just a loading screen which tells the user that he has to verify his email.

But now: How can I continuously listen, if the users email is verified or not and send him (when true) to the Homescreen?

I'm new to Flutter and I don't know if I have to use a Streams or Observables or a while Loop or setState() or something else for such a boolean check. And I also don't know how to setup a solution.

This is my basic code for register a user:

import 'package:cloud_firestore/cloud_firestore.dart';
import 'dart:async';

class AuthService {
  final FirebaseAuth _auth = FirebaseAuth.instance;
  final Firestore _db = Firestore.instance;

  Future<FirebaseUser> get getUser => _auth.currentUser();

  Stream<FirebaseUser> get user => _auth.onAuthStateChanged;

  Future<FirebaseUser> edubslogin(String email, String password) async {
    try {
      final FirebaseUser user = await _auth.createUserWithEmailAndPassword(
        email: email,
        password: password,
      );
     
      await user.sendEmailVerification();
      
      //email verification somewhere here
    
      updateUserData(user);
      return user;
    } catch (error) {
      print(error);
      return null;
    }
  }

I've tried this:

     if (user.isEmailVerified == true) {
        
        //go to Homescreen
        return true; 
      } else {

        //show verification screen(loading spinner)
        return false;
      }

But I don't get a boolean value true out of isEmailVerified.

What do I have to do?

Answer

Alisson Oliveira picture Alisson Oliveira · Mar 1, 2020

I just faced the same situation in my app. My solution was to create a periodic timer into the initState method of a strategic route to hold the app until the e-mail is verified. It is not so elegant as using a listener but works fine.

bool _isUserEmailVerified;
Timer _timer;

@override
void initState() {
    super.initState();
    // ... any code here ...
    Future(() async {
        _timer = Timer.periodic(Duration(seconds: 5), (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();
    }
}