繁体   English   中英

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

[英]how do I verify a new user's email in Flutter and Firebase before granting them access to the app?

我是 Flutter 的新手,也是开发人员的新手。 我已经查看了有关此主题的数十个 Stackoverflow 答案,阅读了有关验证电子邮件的 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',
      );
    }
  }

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM