You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter Firestore使用StreamBuilder获取到非当前用户数据如何解决

问题根因与修复方案

核心问题定位

  • 你当前的UID是一次性静态获取的:代码中final uid = _auth.currentUser!.uid;只会在变量初始化时读取一次当前登录用户的ID,后续切换账号登录/登出操作不会触发这个值更新,导致一直用首次获取的UID查询数据,自然返回的是其他账号的资料。
  • 没有监听FirebaseAuth的登录状态变化,无法在用户切换时自动更新查询的数据源。
  • 缺少空安全校验,当登录状态异常时data!强制取值会触发崩溃。
  • 重复创建多个StreamBuilder监听同一个流,属于不必要的性能浪费。

修复步骤

1. 改造为动态监听登录状态,动态生成查询流

不要提前写死UID和Firestore流,改为先监听用户登录状态,再根据当前登录用户动态生成对应的Profile查询流,示例代码如下:

// 首先引入FirebaseAuth实例
final FirebaseAuth _auth = FirebaseAuth.instance;

@override
Widget build(BuildContext context) {
  // 嵌套两层StreamBuilder,第一层监听登录状态变化
  return StreamBuilder<User?>(
    stream: _auth.authStateChanges(),
    builder: (context, authSnapshot) {
      // 未登录状态处理
      if (!authSnapshot.hasData) {
        return const Center(child: Text('请先登录'));
      }
      // 获取当前登录用户的UID,用户切换时会自动更新
      final String currentUid = authSnapshot.data!.uid;
      // 动态生成对应当前用户的Profile查询流
      final Stream<DocumentSnapshot<Map<String, dynamic>>> profileStream = FirebaseFirestore
          .instance
          .collection('users')
          .doc(currentUid)
          .collection('Profile')
          .doc('Personal details')
          .snapshots();
      
      // 第二层监听Profile数据变化,只用一个StreamBuilder获取所有字段即可
      return StreamBuilder<DocumentSnapshot<Map<String, dynamic>>>(
        stream: profileStream,
        builder: (context, profileSnapshot) {
          if (profileSnapshot.hasError) {
            return const Text('数据加载失败');
          }
          if (profileSnapshot.connectionState == ConnectionState.waiting) {
            return const CircularProgressIndicator();
          }
          // 空数据校验
          if (!profileSnapshot.hasData || !profileSnapshot.data!.exists) {
            return const Text('未找到用户资料');
          }
          final profileData = profileSnapshot.data!.data()!;
          
          // 你的原有UI布局
          return Column(
            children: [
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  const Text('First name'),
                  const SizedBox(width: 40),
                  Text(profileData['First name'] ?? ''),
                ],
              ),
              const Divider(color: Colors.black),
              const SizedBox(height: 10),
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  const Text('Last name'),
                  const SizedBox(width: 40),
                  Text(profileData['Last name'] ?? '', style: boldFont),
                ],
              ),
              // 其余UI保持不变
            ],
          );
        },
      );
    },
  );
}

2. 新增Firestore安全规则(强制数据隔离,必加)

在Firebase控制台的Firestore安全规则中添加如下配置,从服务端层面禁止用户访问其他账号的数据,就算前端代码出错也不会泄露他人信息:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /users/{userId}/{document=**} {
      allow read, write: if request.auth != null && request.auth.uid == userId;
    }
  }
}

内容的提问来源于stack exchange,提问作者reeco

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 13:06:07