how do I verify a new user's email in Flutter and Firebase before granting them access to the app?
343
I think you just don't initiate Auth()
late AuthBase auth;
late Timer timer;
User? user;
bool isUserEmailVerified = false;
@override
void initState() {
super.initState();
auth = Auth();
user = auth.currentUser;
user?.sendEmailVerification();
timer = Timer.periodic(
const Duration(
seconds: 5,
),
(timer) {
checkEmailVerified();
},
);
}
Author by
Carleton Y
Updated on December 16, 2022Comments
-
Carleton Y over 1 year
I am trying to have new users create an account, receive a verification email and then only be granted access to the app once they have clicked the verification link sent by Firebase. I am not getting any errors but there are clearly shortcomings in my code. The new user information is accepted and stored by Firestore and a verification email is sent but once the verification link is clicked the user remains on the Verify page instead of navigating to the HomePage (called Jobs Page in this code).
I cannot figure this out after days of trying so any help would be greatly appreciated. I have included several pages of my code. Thanks in advance!
abstract class AuthBase { User? get currentUser; Stream<User?> authStateChanges(); Future<User?> signInWithEmailAndPassword(String email, String password); Future<void> createUserWithEmailAndPasswordVerify( String email, String password); Future<void> signOut(); } class Auth implements AuthBase { // Value that retrieves an instance of the FirebaseAuth object. This is used for managing users between the app and the Firebase backend final _firebaseAuth = FirebaseAuth.instance; @override Stream<User?> authStateChanges() => _firebaseAuth.authStateChanges(); @override User? get currentUser => _firebaseAuth.currentUser; @override Future<User?> signInWithEmailAndPassword( String email, String password) async { final userCredential = await _firebaseAuth.signInWithCredential( EmailAuthProvider.credential( email: email, password: password, ), ); return userCredential.user; } @override Future<User?> createUserWithEmailAndPasswordVerify( String email, String password) async { final userCredential = await _firebaseAuth.createUserWithEmailAndPassword( email: email, password: password, ); try { await userCredential.user?.sendEmailVerification(); } catch (e) { print( 'An error occurred while trying to send email verification', ); } return userCredential.user; } @override Future<void> signOut() async { await GoogleSignIn().signOut(); await _firebaseAuth.signOut(); } } class VerifyPage extends StatefulWidget { const VerifyPage({ Key? key, }) : super(key: key); @override State<VerifyPage> createState() => _VerifyPageState(); } class _VerifyPageState extends State<VerifyPage> { AuthBase? auth; Timer? timer; User? user; bool isUserEmailVerified = false; @override void initState() { super.initState(); user = auth?.currentUser; user?.sendEmailVerification(); timer = Timer.periodic( const Duration( seconds: 5, ), (timer) { checkEmailVerified(); }, ); } Future<void> checkEmailVerified() async { user = auth?.currentUser; await user?.reload(); final signedInUser = user; if (signedInUser != null && signedInUser.emailVerified) { timer?.cancel(); Navigator.pushReplacement( context, MaterialPageRoute( builder: (context) => const JobsPage(), ), ); } } @override void dispose() { timer?.cancel(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( leading: Container(), title: const Text('Verify Email'), ), body: const Center( child: Padding( padding: EdgeInsets.all(16.0), child: Text( 'An email has just been sent to your email. Click on the link provided to complete registration.', style: TextStyle( fontSize: 20.0, ), ), ), ), ); } }
code from email sign in form
Future<void> _submitVerify() async { try { await model.submitVerify(context); Navigator.pushReplacement( context, MaterialPageRoute( builder: (context) => const VerifyPage(), ), ); } on FirebaseAuthException catch (e) { showExceptionAlertDialog( context, exception: e, title: 'Sign In Failed', ); } }
-
Carleton Y over 2 yearsyour answer is exactly the medicine my problem needed. It worked perfectly. I can admit I would not have figured this out on my own. Thank you for being generous with your time and providing a solution.