在授予新用户访问应用程序的访问权限之前,如何在 Flutter 和 Firebase 中验证新用户的电子邮件?

Posted

技术标签:

【中文标题】在授予新用户访问应用程序的访问权限之前,如何在 Flutter 和 Firebase 中验证新用户的电子邮件?【英文标题】:how do I verify a new user's email in Flutter and Firebase before granting them access to the app? 【发布时间】:2021-12-21 10:49:33 【问题描述】:

我是 Flutter 的新手,也是开发人员的新手。我已经查看了有关此主题的数十个 *** 答案,阅读了有关验证电子邮件的 FlutterFire 文档,并查看了几篇 Medium 文章以寻找答案。文档写得很好,文章也写得很好,但对于没有经验的开发人员来说,有些事情并不容易理解。

我正在尝试让新用户创建一个帐户,接收一封验证电子邮件,然后只有在他们点击 Firebase 发送的验证链接后才被授予访问应用程序的权限。我没有收到任何错误,但我的代码明显存在缺陷。 Firestore 接受并存储新的用户信息并发送验证电子邮件,但一旦单击验证链接,用户就会停留在验证页面上,而不是导航到主页(在此代码中称为工作页面)。

经过几天的尝试,我无法弄清楚这一点,因此我们将不胜感激。我已经包含了几页我的代码。提前致谢!

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,
            ),
          ),
        ),
      ),
    );
  

电子邮件登录表单中的代码

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',
      );
    
  

【问题讨论】:

【参考方案1】:

我认为你只是不启动 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();
      ,
    );
  

【讨论】:

你的答案正是我的问题所需要的药物。它工作得很好。我可以承认我自己不会想到这一点。感谢您抽出宝贵的时间并提供解决方案。 不客气。

以上是关于在授予新用户访问应用程序的访问权限之前,如何在 Flutter 和 Firebase 中验证新用户的电子邮件?的主要内容,如果未能解决你的问题,请参考以下文章

如何授予用户对 SQL Server 中数据库的读取权限?

如何在gke中为用户授予名称空间访问权限?

第三方支付处理并在支付完成后授予用户访问权限

如何测试是不是从包含应用程序授予“允许完全访问”权限?

如何使用 Appsync 在 cognito 中授予对某些用户组的访问权限

如何授予用户级别访问私有 GitLab 存储库的权限?