StreamBuilder切换用户后无法加载数据,求代码审查
问题根源
核心问题出在常量kPAYEES_NODE的初始化逻辑:它在APP启动时就绑定了第一个登录用户的UID,切换用户后这个常量不会自动更新,导致DashboardPage始终监听旧用户的数据库节点,自然加载不到新用户的数据。
修复方案
把固定的常量引用改成动态获取当前用户节点的方法,确保每次进入DashboardPage时,都根据当前登录用户的UID生成正确的数据库引用。
步骤1:修改常量定义(constants.dart)
将原来的常量替换为动态方法:
// 替换原有的kUSER_NODE和kPAYEES_NODE常量 DatabaseReference getUserNode() { final uid = FirebaseAuth.instance.currentUser?.uid; if (uid == null) throw StateError("当前无登录用户"); return FirebaseDatabase.instance.ref('users/$uid'); } DatabaseReference getPayeesNode() => getUserNode().child('payees');
步骤2:更新DashboardPage的StreamBuilder
在DashboardPage中使用动态方法获取数据流,替代固定常量:
body: StreamBuilder( // 替换原有的kPAYEES_NODE.onValue stream: getPayeesNode().onValue, builder: (context, snapshot) { final payees = <Payee>[]; if (!snapshot.hasData) { return const Center(child: Text('No Data')); } else { final payeeData = (snapshot.data!).snapshot.value as Map<Object?, dynamic>?; // 增加空判断,避免空指针异常 if (payeeData != null) { payeeData.forEach((key, value) { final dataLast = Map<String, dynamic>.from(value); final payee = Payee( id: dataLast['id'], name: dataLast['name'], note: dataLast['note'] ); payees.add(payee); }); } return ListView.builder( shrinkWrap: true, itemCount: payees.length, itemBuilder: (BuildContext context, int index) { return ListTile( title: Text(payees[index].name), subtitle: Text(payees[index].id) ); } ); } }, ),
额外优化:避免强制解包风险
修改AuthService中的getUid方法,增加空判断防止未登录时崩溃:
static String? getUid() => FirebaseAuth.instance.currentUser?.uid;
修复原理
当用户切换登录时,AuthService中的StreamBuilder会监听到authStateChanges的状态变化,重新构建DashboardPage。此时调用getPayeesNode()会自动获取新登录用户的UID,生成正确的数据库节点引用,数据流会自动加载新用户的数据,无需重启APP。
内容的提问来源于stack exchange,提问作者Andy
相关产品推荐
相关产品推荐

