Flutter聊天应用区分消息收发方时FutureBuilder传currentUser报错如何解决
问题原因
你使用的firebase_auth插件为0.18.0及以上版本,该版本之后FirebaseAuth.instance.currentUser已经从返回Future<User>的异步方法,调整为直接同步返回User?类型的属性,不需要异步等待。你将User类型的对象传入FutureBuilder要求的Future类型的future参数,就会触发类型不匹配的报错。
解决方案
方案1:移除外层FutureBuilder(推荐)
既然currentUser支持直接同步获取,不需要异步等待,直接删除外层的FutureBuilder即可,修改后代码如下:
class Messages extends StatelessWidget { @override Widget build(BuildContext context) { // 直接同步获取当前登录用户 final User? currentUser = FirebaseAuth.instance.currentUser; // 增加未登录场景的兜底处理,避免空异常 if (currentUser == null) { return const Center(child: Text('请先登录后使用聊天功能')); } return StreamBuilder( stream: FirebaseFirestore.instance .collection('chat') .orderBy('createdAt', descending: true) .snapshots(), builder: (ctx, chatSnapshot) { if (chatSnapshot.connectionState == ConnectionState.waiting) { return const Center( child: CircularProgressIndicator(), ); } final chatDocs = chatSnapshot.data?.docs ?? []; return ListView.builder( reverse: true, itemCount: chatDocs.length, itemBuilder: (ctx, index) => MessageBubble( chatDocs[index]['text'], // 直接用同步获取的当前用户id做对比即可 chatDocs[index]['userId'] == currentUser.uid, key: ValueKey(chatDocs[index].id), ), ); }); } }
方案2:保留FutureBuilder的兼容写法
如果你的业务逻辑需要保留FutureBuilder结构,可以把currentUser手动包装为Future类型传入:
future: Future.value(FirebaseAuth.instance.currentUser),
该方案属于绕开类型校验的妥协写法,运行效率低于方案1,不推荐使用。
额外优化说明
- 原代码中的
chatSnapshot.data.docs没有做空值校验,容易触发空异常,上面示例中已经修改为chatSnapshot.data?.docs ?? []做兼容处理 - 旧版Firebase SDK中的
documentID属性已经废弃,新版请使用id属性获取文档唯一标识
内容的提问来源于stack exchange,提问作者Mr Rock
相关产品推荐
相关产品推荐

