Flutter登录页实现单字段支持邮箱/手机号登录求助
实现单个输入框支持邮箱/手机号登录的解决方案
步骤1:添加验证工具方法
在_LoginState类中添加两个工具方法,用于判断输入内容是邮箱还是手机号:
// 判断是否为合法邮箱 bool isEmail(String input) => RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$').hasMatch(input); // 判断是否为合法手机号(可根据地区调整正则,示例为国际通用格式) bool isPhoneNumber(String input) => RegExp(r'^\+?[0-9]{10,15}$').hasMatch(input);
步骤2:修改输入框验证规则
更新TextFormField的validator,使其支持邮箱或手机号的验证:
validator: (value) { if (value == null || value.isEmpty) { return '请输入邮箱或手机号'; } else if (!isEmail(value) && !isPhoneNumber(value)) { return '请输入有效的邮箱或手机号'; } return null; }
步骤3:修改登录逻辑
更新userlogin方法,根据输入内容的类型选择对应的登录方式:
// 先导入cloud_firestore依赖 import 'package:cloud_firestore/cloud_firestore.dart'; userlogin() async { try { String loginId = emailController.text.trim(); String password = passwordController.text.trim(); UserCredential? userCredential; if (isEmail(loginId)) { // 邮箱直接登录 userCredential = await FirebaseAuth.instance.signInWithEmailAndPassword( email: loginId, password: password, ); } else if (isPhoneNumber(loginId)) { // 通过手机号查询Firestore中关联的邮箱 QuerySnapshot snapshot = await FirebaseFirestore.instance .collection('users') // 替换为你的用户集合名称 .where('phoneNumber', isEqualTo: loginId) .limit(1) .get(); if (snapshot.docs.isEmpty) { ScaffoldMessenger.of(context).showSnackBar(SnackBar( backgroundColor: Colors.orangeAccent, content: Text( '未找到该手机号对应的用户', style: GoogleFonts.limelight( fontSize: 15.0, color: Colors.white, ), ), )); return; } // 获取关联的邮箱后执行登录 String userEmail = snapshot.docs.first['email']; userCredential = await FirebaseAuth.instance.signInWithEmailAndPassword( email: userEmail, password: password, ); } else { ScaffoldMessenger.of(context).showSnackBar(SnackBar( backgroundColor: Colors.orangeAccent, content: Text( '请输入有效的邮箱或手机号', style: GoogleFonts.limelight( fontSize: 15.0, color: Colors.white, ), ), )); return; } print(userCredential.user?.uid); await storage.write(key: "uid", value: userCredential.user?.uid); Navigator.pushReplacement( context, MaterialPageRoute( builder: (context) => Waiting(), ), ); } on FirebaseAuthException catch (e) { String message = ''; if (e.code == 'user-not-found') { message = '未找到该用户'; } else if (e.code == 'wrong-password') { message = '密码错误'; } else { message = '登录失败:${e.code}'; } ScaffoldMessenger.of(context).showSnackBar(SnackBar( backgroundColor: e.code == 'wrong-password' ? Colors.redAccent : Colors.orangeAccent, content: Text( message, style: GoogleFonts.limelight( fontSize: 15.0, color: Colors.white, ), ), )); } catch (e) { ScaffoldMessenger.of(context).showSnackBar(SnackBar( backgroundColor: Colors.redAccent, content: Text( '登录出错:${e.toString()}', style: GoogleFonts.limelight( fontSize: 15.0, color: Colors.white, ), ), )); } }
步骤4:添加依赖
在pubspec.yaml中添加Cloud Firestore的依赖(如果尚未添加):
dependencies: flutter: sdk: flutter cloud_firestore: ^4.17.1 # 使用最新版本 # 其他已有的依赖...
注意事项
- 确保你的Firestore用户集合中,每个用户文档都存储了
phoneNumber和email字段,且手机号字段唯一 - 根据用户所在地区调整手机号的正则表达式,比如中国手机号可使用
^1[3-9]\d{9}$ - 如果你是通过Firebase Auth的手机号OTP方式注册用户,需要调整登录逻辑,改用OTP验证而非密码登录
内容的提问来源于stack exchange,提问作者Abu Bakar Farooq
相关产品推荐
相关产品推荐

