Flutter对接Firebase时StreamProvider始终返回null问题求助
问题原因&修复方案
1. 空值读取不匹配
你在AuthWrapper中声明的StreamProvider类型为可空的AppUserData?,且设置了initialData: null,但Schedules组件中直接读取非空类型的Provider.of<AppUserData>(context),首次渲染时拿到初始值null就会直接触发类型不匹配报错。
修复方法:修改Schedules组件的取值逻辑,新增空判断和加载状态:
@override Widget build(BuildContext context) { // 读取可空类型 AppUserData? userData = Provider.of<AppUserData?>(context); // 空值时展示加载状态 if (userData == null) { return const Scaffold( body: Center(child: CircularProgressIndicator()), ); } // 有数据时再渲染正常页面 return Scaffold( appBar: AppBar(title: Text(userData.name)), body: ElevatedButton.icon( onPressed: () async { await _auth.signOut(); }, icon: Icon(Icons.person), label: Text("logout"), ), drawer: NavigationDrawer(), ); }
如果不想加加载状态,也可以把StreamProvider的initialData改成默认的AppUserData对象,不要设为null。
2. 类型转换&字段映射错误
appUserDataFromSnapshot方法存在两处逻辑错误:
- 你错误将
snapshot.data()(返回Map<String,dynamic>类型)强转为DocumentSnapshot类型,会触发类型转换异常 - 写入数据库的字段为
churchID、isOnChurch,读取时用了church、isInChurch,字段不匹配拿不到值
修复方法:修改转换方法:
// 直接接收DocumentSnapshot类型参数 AppUserData appUserDataFromSnapshot(DocumentSnapshot snapshot) { // 处理文档不存在的情况(新用户未初始化数据时触发) if (!snapshot.exists) { return AppUserData( name: 'no name', church: 'no church', isInChurch: false, ); } Map<String, dynamic> data = snapshot.data() as Map<String, dynamic>; return AppUserData( name: data['name'] ?? 'no name', // 和写入的字段名保持一致 church: data['churchID'] ?? 'no church', isInChurch: data['isOnChurch'] ?? false, ); }
同步修改流的返回类型和Provider声明保持一致:
Stream<AppUserData?> get appUserData { print('successss'); return appUserDataCollection .doc(uid) .snapshots() .map(appUserDataFromSnapshot); }
3. 新用户数据初始化
如果是新注册的用户,Firestore中还没有对应的AppUsers文档,建议在注册成功后调用一次updateAppUserdata方法初始化用户数据,避免每次读取都走默认值逻辑。
内容的提问来源于stack exchange,提问作者Agapito Hampaslupa
相关产品推荐
相关产品推荐

