不使用StreamBuilder如何检查Firestore快照流的连接状态?
解决方案
你可以通过在FirebaseAuthService中新增可观测的连接状态变量,配合流的操作符跟踪状态,全程用GetX的响应式能力实现,不需要引入StreamBuilder。
第一步:修改FirebaseAuthService类
先新增两个可观测变量用于跟踪流状态:
// 标识是否正在拉取Firestore用户的首次数据 RxBool isLoadingUser = true.obs; // 可选:标识当前用户数据是否来自本地缓存(可用于离线状态提示) RxBool isUserFromCache = false.obs;
然后改造streamFirestoreUser方法,在流的生命周期节点更新状态:
Stream<LocalUser> streamFirestoreUser() { isLoadingUser.value = true; final uid = firebaseUserObs.value?.uid; if (uid == null) { isLoadingUser.value = false; return const Stream.empty(); } return _db .collection('Users') .doc(uid) .snapshots() .map((snapshot) { // 更新缓存状态 isUserFromCache.value = snapshot.metadata.isFromCache; // 首次收到快照即关闭加载状态 if (isLoadingUser.value) isLoadingUser.value = false; if (snapshot.exists) { print('=========EXISTS=========='); return LocalUser.fromJson(uid, snapshot.data()); } else { print('=========DOES NOT EXIST=========='); return null; } }) // 发生异常时也关闭加载状态,避免无限加载 .doOnError((error, stackTrace) { isLoadingUser.value = false; debugPrint("拉取用户数据异常: $error"); }); }
记得在登出逻辑中重置状态,避免下次登录复用旧状态:
Future<void> signOut() async { await FirebaseAuth.instance.signOut(); firestoreUserObs.value = null; // 重置加载状态 isLoadingUser.value = true; isUserFromCache.value = false; }
第二步:修改根Widget的判断逻辑
直接在GetX的builder中优先判断加载状态即可:
GetX<FirebaseAuthService>( builder: (_) { // 加载状态下优先展示加载页 if (auth.isLoadingUser.value) { return const Scaffold(body: Center(child: CircularProgressIndicator())); } if (auth.localUser != null) { bool isAnon = auth.localUser?.isAnonymous ?? false; if (!isAnon) { if (collectInfo.displayCollectInfoScreen) { return CollectInfoScreen(); } else { return HomeWrapper(); } } else { if (isDisplayedAnon) { return HomeWrapper(); } else { return AnonUserIntroScreen(); } } } else { return AuthWrapper(); } }, ),
这个方案完全依赖GetX的响应式更新,不会引入StreamBuilder的导航重建问题,所有状态统一在Service层维护,后续如果需要扩展离线提示、加载重试逻辑也可以直接在Service层修改。
内容的提问来源于stack exchange,提问作者Ali Alqallaf
相关产品推荐
相关产品推荐

