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

Flutter使用StreamBuilder取Firestore数据切换登录后用户信息不刷新问题

问题根因

  • 当前代码监听的是整个users集合的全量快照,并且遍历所有用户文档渲染为Stack子节点,多个用户的信息层叠展示,最终呈现的永远是排在列表前面/缓存优先的用户数据,没有过滤当前登录用户的专属文档
  • 没有绑定FirebaseAuth的登录状态监听,切换用户登录后不会触发Stream重新拉取新用户的对应数据

修改后的完整代码

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';

class UserDrawer extends StatefulWidget {
  UserDrawer({Key? key}) : super(key: key);

  @override
  _UserDrawerState createState() => _UserDrawerState();
}

class _UserDrawerState extends State<UserDrawer> {
  final FirebaseAuth _auth = FirebaseAuth.instance;
  final FirebaseFirestore _firestore = FirebaseFirestore.instance;

  @override
  Widget build(BuildContext context) {
    return Drawer(
      child: SafeArea(
        child: Scaffold(
          backgroundColor: Theme.of(context).primaryColor,
          // 先监听Auth登录状态变更
          body: StreamBuilder<User?>(
            stream: _auth.authStateChanges(),
            builder: (context, authSnapshot) {
              // 未登录状态展示兜底
              if (!authSnapshot.hasData || authSnapshot.data == null) {
                return const Center(child: Text('请先登录'));
              }
              final currentUserId = authSnapshot.data!.uid;
              // 只拉取当前登录用户的单条文档
              return StreamBuilder<DocumentSnapshot<Map<String, dynamic>>>(
                stream: _firestore.collection('users').doc(currentUserId).snapshots(),
                builder: (context, userSnapshot) {
                  if (!userSnapshot.hasData || userSnapshot.data?.data() == null) {
                    return const Center(child: Text('用户数据加载中'));
                  }
                  final userData = userSnapshot.data!.data()!;
                  return Stack(
                    children: [
                      Container(
                        padding: const EdgeInsets.only(top: 400),
                        decoration: BoxDecoration(
                            color: Theme.of(context).primaryColorLight,
                            borderRadius: const BorderRadius.only(
                                bottomLeft: Radius.circular(80))),
                        child: Row(
                          mainAxisAlignment: MainAxisAlignment.center,
                          crossAxisAlignment: CrossAxisAlignment.center,
                          children: [
                            Expanded(
                                child: ElevatedButton(
                                    onPressed: () {}, child: const Text('data'))),
                            const SizedBox(
                              width: 8,
                            ),
                            Expanded(
                                child: ElevatedButton(
                                    onPressed: () {}, child: const Text('data'))),
                          ],
                        ),
                      ),
                      Container(
                        padding: const EdgeInsets.only(top: 105),
                        height: 300,
                        width: double.infinity,
                        decoration: BoxDecoration(
                            color: Theme.of(context).primaryColorDark,
                            borderRadius: const BorderRadius.only(
                                bottomLeft: Radius.circular(120))),
                        child: Column(
                          children: [
                            const CircleAvatar(
                              radius: 40,
                              backgroundColor: Colors.blueAccent,
                            ),
                            Text(
                              userData['username'],
                              style: const TextStyle(
                                  fontWeight: FontWeight.bold,
                                  fontSize: 20),
                            ),
                          ],
                        ),
                      ),
                      Container(
                        padding: const EdgeInsets.symmetric(
                            horizontal: 20, vertical: 10),
                        height: 100,
                        width: double.infinity,
                        child: const Text(
                          'Profile',
                          style: TextStyle(
                            fontSize: 24,
                            fontWeight: FontWeight.bold,
                          ),
                        ),
                        decoration: BoxDecoration(
                            color: Theme.of(context).primaryColorLight,
                            borderRadius: const BorderRadius.only(
                                bottomLeft: Radius.circular(80))),
                      ),
                    ],
                  );
                }
              );
            }
          ),
        ),
      ),
    );
  }
}

核心修改点

  • 新增监听FirebaseAuth.instance.authStateChanges(),用户登录/登出操作会自动触发组件重绘
  • 不再拉取整个users集合的全量数据,而是通过当前登录用户的UID直接拉取对应用户的单条文档,避免冗余数据和渲染冲突
  • 移除了原代码中遍历所有用户文档的逻辑,仅渲染当前登录用户的信息

内容的提问来源于stack exchange,提问作者Md. Fazle Rabbi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 07:09:04