Firebase authStateChanges映射自定义用户模型返回null问题排查
问题产生原因
- 核心问题出在
_userFromFirebaseUser的异步逻辑处理错误:方法内部调用了异步方法getUserFromUserId(),但没有等待异步操作执行完成就直接返回了_unicoUser变量,该变量在返回时还未被异步回调赋值,始终为初始值null。 - 控制台输出的日志顺序已经验证了该逻辑错误:先打印
snapshot is: null,之后才打印异步回调中的user id: xxx,说明异步接口返回结果的时机晚于方法返回的时机。 - 此外你当前使用的
map流转换仅支持同步转换逻辑,无法处理需要等待异步结果的场景,因此最终输出的流始终发出null值。
修复方案
1. 调整转换方法与流转换逻辑
将同步的map转换替换为支持异步处理的asyncMap,同时修改用户转换方法为异步,等待数据库查询结果返回后再回传自定义用户对象:
// 改造为异步转换方法 Future<UnicoUser?> _userFromFirebaseUser(User? user) async { if (user == null) { return null; } // 等待数据库查询完成后再返回结果 return await DatabaseService(uid: user.uid).getUserFromUserId(); } // 流转换改用asyncMap支持异步逻辑 Stream<UnicoUser?> get unicoUser { return _auth.authStateChanges().asyncMap(_userFromFirebaseUser); }
2. 可选异常处理优化
如果需要兼容数据库查询失败的场景,可以在转换方法中增加异常捕获逻辑,错误会被StreamBuilder的hasError分支捕获:
Future<UnicoUser?> _userFromFirebaseUser(User? user) async { if (user == null) { return null; } try { return await DatabaseService(uid: user.uid).getUserFromUserId(); } catch (e) { print('查询用户数据失败: $e'); rethrow; } }
修改完成后原有StreamBuilder代码无需调整,即可正常接收到非空的自定义用户对象。
内容的提问来源于stack exchange,提问作者Oz Cohen
相关产品推荐
相关产品推荐

