Flutter接入Firebase商户注册时调用null对象uid报错如何解决?
问题解决办法
报错
getter 'uid' was called on null的根本原因是执行saveVendorDataToDb方法时,FirebaseAuth.instance.currentUser返回了null,导致调用user.uid失败。
错误诱因
- 注册请求出现异常(比如密码太弱、邮箱已被注册)时,
registerVendor方法会返回null的UserCredential,但你的前端逻辑没有做异常判断,依然会继续执行后续的上传图片、保存商户数据逻辑,此时还没有登录的用户,currentUser自然为null - 就算注册成功,部分场景下
FirebaseAuth.instance.currentUser存在同步延迟,刚注册完成就立刻调用可能还没拿到最新的登录状态
修复方案
方案1(更稳妥,推荐):直接透传注册返回的uid,不依赖currentUser
第一步:修改saveVendorDataToDb方法,新增uid参数
不用再读取当前登录用户,直接用注册接口返回的uid,避免同步问题:
/// 保存商户数据到Firestore Future<void> saveVendorDataToDb( {String uid, // 新增uid参数 String url, String shopName, String mobile_number, String email, String location, String desc})async { DocumentReference _vendors = FirebaseFirestore.instance.collection('vendors').doc(uid); await _vendors.set({ // 补充await,保证数据保存完成再返回 'shopName': shopName, 'mobile': mobile_number, 'email': email, 'location': location, 'description': desc, 'shopOpen': true, 'rating': 0.00, 'totalRating': 0, 'isTopPicked': true, }); return null; }
第二步:修改前端注册逻辑,校验注册结果后透传uid
新增注册结果判断,只有注册成功才执行后续逻辑,同时把拿到的uid传给保存方法:
FlatButton( color: Theme.of(context).primaryColor, onPressed: () { if (_authData.isPicAvail == true) { if (_formKey.currentState.validate()) { _authData .registerVendor(email, password) .then((credential) { // 新增判断:只有注册成功拿到用户信息才继续操作 if (credential?.user != null) { final uid = credential.user.uid; uploadFile(_authData.image.path).then((url) { if (url != null) { _authData.saveVendorDataToDb( uid: uid, // 传入注册拿到的uid url: url, shopName: _shopNameTextController.text, mobile_number: _mobilePhoneTextController.text, email: _emailTextController.text, location: _locationTextController.text, desc: _descriptionTextController.text, ).then((value) { setState(() { _formKey.currentState.reset(); }); Navigator.pushReplacementNamed(context, HomeScreen.id); }); }else{ scaffoldMessenge('Failed to upload shop profile picture'); } }); } // 注册失败直接弹提示 else { scaffoldMessenge(_authData.error ?? '注册失败,请重试'); } }); } } else { scaffoldMessenge("Shop profile picture is needed"); } }, child: Text( 'Register', style: TextStyle(color: Colors.white), ) ),
方案2(临时修复,不推荐):给currentUser加空判断
如果不想修改方法参数,也可以在保存数据前增加空判断和等待逻辑:
Future<void> saveVendorDataToDb( {String url, String shopName, String mobile_number, String email, String location, String desc})async { User user = FirebaseAuth.instance.currentUser; // 新增空判断,如果currentUser为空就等待auth状态同步 if (user == null) { user = await FirebaseAuth.instance.authStateChanges().first; } if (user != null) { DocumentReference _vendors = FirebaseFirestore.instance.collection('vendors').doc(user.uid); await _vendors.set({ 'shopName': shopName, 'mobile': mobile_number, 'email': email, 'location': location, 'description': desc, 'shopOpen': true, 'rating': 0.00, 'totalRating': 0, 'isTopPicked': true, }); } return null; }
内容的提问来源于stack exchange,提问作者ryan chandra
相关产品推荐
相关产品推荐

