Firebase注册时出现‘Given String is empty or null’错误求助
问题排查与修复方案
错误定位
先通过添加异常捕获,明确错误来自Firebase Auth还是Firestore:
- 在
signUp()的catch块中打印具体错误信息:on FirebaseAuthException catch (e) { print('Auth错误详情: ${e.message}'); } - 在
createUser()中添加try-catch捕获Firestore异常:Future createUser(Profiles profile) async { try { final docUser = FirebaseFirestore.instance.collection('profiles').doc(); profile.id = docUser.id; final json = profile.toJson(); await docUser.set(json); } catch (e) { print('Firestore错误详情: $e'); } }
核心排查点与修复
1. 异步调用顺序问题(最可能原因)
当前onPressed中signUp()和createUser()并行执行,且signUp()里的popUntil会直接回到首页,导致当前页面的TextEditingController被销毁,后续读取text时为空。
修复代码:
LoginButton( onPressed: () async { // 等待注册完成 await signUp(); // 确认注册成功后再创建用户 if (FirebaseAuth.instance.currentUser != null) { final user = Profiles( id: id.v1(), email: email.text.trim(), gender: selectedGender == 1 ? 'Erkek' : 'Kadın', name: name.text.trim(), username: username.text.trim(), ); await createUser(user); } }, ),
同时修改signUp(),仅关闭加载弹窗,不要直接跳转首页(跳转逻辑可放在注册成功后):
Future signUp() async { final loadingDialog = showDialog( barrierDismissible: false, context: context, builder: (context) => const Center(child: CircularProgressIndicator()), ); try { await FirebaseAuth.instance.createUserWithEmailAndPassword( email: email.text.trim(), password: password.text.trim(), ); // 注册成功后再跳转(可选,根据需求调整) // navigatorKey.currentState!.popUntil((route) => route.isFirst); } on FirebaseAuthException catch (e) { print('Auth错误详情: ${e.message}'); } finally { // 无论成功失败,关闭加载弹窗 Navigator.of(context).pop(); } }
2. TextEditingController状态检查
确认所有输入框的controller已正确初始化且未被意外重置:
- 在State类中初始化:
final email = TextEditingController(); final password = TextEditingController(); final name = TextEditingController(); final username = TextEditingController(); - 检查代码中是否存在
controller.clear()或重新赋值为null的逻辑,避免输入内容被清空。
3. 输入值非空校验
在调用注册和创建用户前,添加非空校验,提前拦截空值:
onPressed: () async { final trimmedEmail = email.text.trim(); final trimmedPassword = password.text.trim(); final trimmedName = name.text.trim(); final trimmedUsername = username.text.trim(); if (trimmedEmail.isEmpty || trimmedPassword.isEmpty || trimmedName.isEmpty || trimmedUsername.isEmpty) { // 提示用户填写完整信息 ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('请填写所有必填字段')), ); return; } await signUp(); if (FirebaseAuth.instance.currentUser != null) { final user = Profiles( id: id.v1(), email: trimmedEmail, gender: selectedGender == 1 ? 'Erkek' : 'Kadın', name: trimmedName, username: trimmedUsername, ); await createUser(user); } },
4. Profiles类与Firestore字段统一
当前Profiles的id在创建对象时生成,又在createUser中被Firestore的doc id覆盖,可简化逻辑:
- 修改Profiles类构造函数,让
id可选:class Profiles { String? id; final String name; final String username; final String gender; final String email; Profiles({ this.id, required this.email, required this.gender, required this.name, required this.username, }); // toJson和fromJson逻辑不变 } - 创建用户时无需提前生成id:
final user = Profiles( email: trimmedEmail, gender: selectedGender == 1 ? 'Erkek' : 'Kadın', name: trimmedName, username: trimmedUsername, );
内容的提问来源于stack exchange,提问作者KKot
相关产品推荐
相关产品推荐

