Flutter Firebase登录后发帖提示邮箱格式错误的解决咨询
问题背景
我在Flutter项目的登录注册模块中遇到了firebase_auth/invalid-email错误,即使使用硬编码的正确邮箱登录也无法解决。登录进入首页发布帖子时控制台报错,以下是相关代码和错误信息:
登录模块代码(login.dart)
import 'package:flutter/material.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter_application_1/home.dart'; import 'package:flutter_application_1/register.dart'; class LoginPage extends StatelessWidget { final TextEditingController usernameController = TextEditingController(); final TextEditingController passwordController = TextEditingController(); Future<void> _signIn(BuildContext context) async { try { String email = usernameController.text.trim(); String password = passwordController.text.trim(); if (!isValidEmail(email)) { showDialog( context: context, builder: (BuildContext context) { return AlertDialog( title: Text('Hata'), content: Text('Geçersiz e-posta adresi biçimi.'), actions: [ TextButton( onPressed: () { Navigator.pop(context); }, child: Text('Tamam'), ), ], ); }, ); return; } UserCredential userCredential = await FirebaseAuth.instance.signInWithEmailAndPassword( email: email, password: password, ); // 登录成功跳转首页 Navigator.of(context).pushReplacement( MaterialPageRoute(builder: (context) => MyHomePage()), ); } catch (e) { showDialog( context: context, builder: (BuildContext context) { return AlertDialog( title: Text('Hata'), content: Text('Geçersiz kullanıcı adı ve/veya şifre.'), actions: [ TextButton( onPressed: () { Navigator.pop(context); }, child: Text('Tamam'), ), ], ); }, ); } } bool isValidEmail(String email) { final emailRegex = RegExp(r'^[\w-]+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]{2,7}$'); return emailRegex.hasMatch(email); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( backgroundColor: Color.fromARGB(255, 0, 0, 0), title: Center( child: Text( 'Kome', style: TextStyle(fontFamily: "DancingScript", color: Color(0xFFFFFFFF)), )), automaticallyImplyLeading: false, ), body: Padding( padding: const EdgeInsets.all(16.0), child: Form( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ TextFormField( controller: usernameController, decoration: InputDecoration(labelText: 'Kullanıcı Adı'), ), TextFormField( controller: passwordController, obscureText: true, decoration: InputDecoration(labelText: 'Şifre'), ), SizedBox(height: 20), ElevatedButton( onPressed: () async { await _signIn(context); }, child: Text('Giriş Yap'), ), TextButton( onPressed: () { Navigator.of(context).push( MaterialPageRoute(builder: (context) => RegisterPage()), ); }, child: Text('Kayıt Ol'), ), ], ), ), ), ); } }
注册模块代码(register.dart)
import 'package:flutter/material.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:flutter_application_1/login.dart'; class RegisterPage extends StatelessWidget { final TextEditingController emailController = TextEditingController(); final TextEditingController usernameController = TextEditingController(); final TextEditingController birthDateController = TextEditingController(); final TextEditingController passwordController = TextEditingController(); final TextEditingController confirmPasswordController = TextEditingController(); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( backgroundColor: const Color.fromARGB(255, 0, 0, 0), title: const Center( child: Text( 'Kome', style: TextStyle(fontFamily: "DancingScript", color: Color(0xFFFFFFFF)), )), automaticallyImplyLeading: false, ), body: Padding( padding: const EdgeInsets.all(16.0), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ _buildTextField(emailController, 'E-posta'), _buildTextField(usernameController, 'Kullanıcı Adı'), _buildTextField(birthDateController, 'Doğum Tarihi'), _buildTextField(passwordController, 'Şifre', obscureText: true), _buildTextField( confirmPasswordController, 'Şifreyi Tekrar Girin', obscureText: true, ), const SizedBox(height: 20), ElevatedButton( onPressed: () async { await _handleRegistration(context); }, child: const Text('Kayıt Ol'), ), ], ), ), ); } Widget _buildTextField( TextEditingController controller, String labelText, { bool obscureText = false, }) { return TextFormField( controller: controller, obscureText: obscureText, decoration: InputDecoration(labelText: labelText), ); } Future<void> _handleRegistration(BuildContext context) async { try { UserCredential userCredential = await FirebaseAuth.instance.createUserWithEmailAndPassword( email: emailController.text, password: passwordController.text, ); // 发送邮箱验证邮件 await userCredential.user!.sendEmailVerification(); await saveUserInformation( userCredential.user!.uid, usernameController.text, emailController.text, birthDateController.text, ); _showSuccessDialog(context); } catch (e, stackTrace) { print('Kayıt Hatası: $e'); print('Stack Trace: $stackTrace'); _showErrorDialog( context, 'Hata', 'Bir hata oluştu.', '$e\n\nStack Trace: $stackTrace', ); } } Future<void> saveUserInformation( String userId, String username, String email, String birthDate, ) async { await FirebaseFirestore.instance.collection('users').doc(userId).set({ 'username': username, 'email': email, 'birthDate': birthDate, 'totalLikes': 0, // 初始点赞数设为0 'totalComments': 0, // 初始评论数设为0 }); print('Saved Username: $username'); print('Saved Email: $email'); print('Saved Birth Date: $birthDate'); } Future<void> _showSuccessDialog(BuildContext context) async { await showDialog<void>( context: context, builder: (BuildContext context) { return AlertDialog( title: const Text('Başarılı'), content: const Text('Kayıt başarıyla tamamlandı.'), actions: <Widget>[ TextButton( onPressed: () { Navigator.of(context).pop(); // 关闭弹窗 Navigator.pushReplacement( context, MaterialPageRoute(builder: (context) => LoginPage()), ); }, child: const Text('Tamam'), ), ], ); }, ); } Future<void> _showErrorDialog( BuildContext context, String title, String content, dynamic error) async { await showDialog<void>( context: context, builder: (BuildContext context) { return AlertDialog( title: Text(title), content: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ Text(content), if (error != null) const SizedBox(height: 10), if (error != null) Text('Hata Detayı: $error'), ], ), actions: <Widget>[ TextButton( onPressed: () { Navigator.of(context).pop(); // 关闭弹窗 }, child: const Text('Tamam'), ), ], ); }, ); } }
错误日志
I/FirebaseAuth( 9310): Logging in as kullanici_email with empty reCAPTCHA token W/System ( 9310): Ignoring header X-Firebase-Locale because its value was null. W/LocalRequestInterceptor( 9310): Error getting App Check token; using placeholder token instead. Error: com.google.firebase.FirebaseException: No AppCheckProvider installed. E/RecaptchaCallWrapper( 9310): Initial task failed for action RecaptchaAction(action=signInWithPassword)with exception - The email address is badly formatted. I/flutter ( 9310): Hata: [firebase_auth/invalid-email] The email address is badly formatted.
尝试的解决方法
我试过硬编码邮箱登录,问题依旧:
Future<User?> _signIn() async { try { UserCredential userCredential = await FirebaseAuth.instance.signInWithEmailAndPassword( email: 'your_email@example.com', password: 'your_password', ); User? user = userCredential.user; return user; } catch (e) { print('Hata: $e'); return null; } }
解决方案
1. 修正登录逻辑的邮箱来源
登录页面输入框标注为“Kullanıcı Adı”,但代码直接将其作为邮箱使用。如果用户输入的是用户名而非邮箱,必然触发格式错误。需调整逻辑:
- 若支持用户名登录,先从Firestore查询用户名对应的邮箱:
Future<void> _signIn(BuildContext context) async { try { String input = usernameController.text.trim(); String password = passwordController.text.trim(); String email; if (isValidEmail(input)) { email = input; } else { // 从Firestore查询用户名对应的邮箱 QuerySnapshot snapshot = await FirebaseFirestore.instance .collection('users') .where('username', isEqualTo: input) .get(); if (snapshot.docs.isEmpty) { showDialog( context: context, builder: (_) => AlertDialog(title: Text('Hata'), content: Text('Kullanıcı bulunamadı')), ); return; } email = snapshot.docs.first['email']; } // 执行登录 UserCredential userCredential = await FirebaseAuth.instance.signInWithEmailAndPassword(email: email, password: password); Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (context) => MyHomePage())); } catch (e) { // 错误处理 showDialog( context: context, builder: (_) => AlertDialog(title: Text('Hata'), content: Text(e.toString())), ); } }
2. 优化邮箱正则表达式
当前正则可能存在覆盖不全的问题,改用更通用的验证规则:
bool isValidEmail(String email) { return RegExp(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$').hasMatch(email); }
3. 检查Firebase初始化与配置
确保main.dart中完成Firebase初始化:
void main() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp(); runApp(const MyApp()); }
同时确认google-services.json(Android)或GoogleService-Info.plist(iOS)已正确添加到项目中。
4. 处理App Check提示
日志中提到No AppCheckProvider installed,虽不是邮箱错误直接原因,但可能影响Auth流程:
- 若不需要App Check,可在Firebase控制台关闭该功能;
- 若需要,需在项目中添加App Check依赖并完成配置。
5. 硬编码测试注意事项
确保硬编码的邮箱是已在Firebase Auth中注册的有效账号,且密码完全匹配,无多余空格或拼写错误。
内容的提问来源于stack exchange,提问作者emirhan.akyazici

