在授予新用户应用程序访问权限之前,如何在 Flutter 和 Firebase 中验证他们的电子邮件?
how do I verify a new user's email in Flutter and Firebase before granting them access to the app?
我正在尝试让新用户创建一个帐户,接收一封验证电子邮件,然后只有在他们点击 Firebase 发送的验证 link 后才被授予访问该应用程序的权限。我没有收到任何错误,但我的代码显然存在缺陷。 Firestore 接受并存储了新的用户信息,并发送了一封验证电子邮件,但是一旦单击验证 link,用户就会停留在验证页面上,而不是导航到主页(在此代码中称为作业页面)。
经过几天的尝试我无法解决这个问题,因此非常感谢您的帮助。我已经包含了几页我的代码。提前致谢!
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();
},
);
}
我正在尝试让新用户创建一个帐户,接收一封验证电子邮件,然后只有在他们点击 Firebase 发送的验证 link 后才被授予访问该应用程序的权限。我没有收到任何错误,但我的代码显然存在缺陷。 Firestore 接受并存储了新的用户信息,并发送了一封验证电子邮件,但是一旦单击验证 link,用户就会停留在验证页面上,而不是导航到主页(在此代码中称为作业页面)。
经过几天的尝试我无法解决这个问题,因此非常感谢您的帮助。我已经包含了几页我的代码。提前致谢!
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();
},
);
}