Flutter Web刷新浏览器时如何从Firestore获取用户数据?
问题分析与解决方案
问题根源
刷新浏览器时,主页initState中直接获取FirebaseAuth.instance.currentUser可能返回null——这是因为Flutter Web刷新后,Firebase Auth需要从本地缓存恢复用户状态,这个过程是异步的。虽然Main中的authStateChanges流已经触发并跳转到主页,但此时主页的currentUser还未完成初始化,导致Firestore查询使用了null的uid,无法获取用户数据,最终name保持初始值。而跳转页面再返回时,Auth状态已稳定,currentUser存在,查询自然正常。
修复方案
通过监听Auth状态变化,确保获取到有效用户后再执行Firestore查询,避免依赖未就绪的currentUser。
修改HomePage代码:
class _UserHomePageState extends State<UserHomePage> { final scaffoldkey = GlobalKey<ScaffoldState>(); String? name = 'Loading...'; // 初始设为加载提示,提升用户体验 String? formattedDate = DateFormat('yyyy-MM-dd').format(DateTime.now()); @override void initState() { super.initState(); // 监听Auth状态变化,确保用户就绪后获取数据 FirebaseAuth.instance.authStateChanges().listen((User? currentUser) { if (currentUser != null) { _getUserData(currentUser); } else { // 用户未登录时的处理(可选) setState(() { name = null; }); } }); } // 传入已确认的User对象,避免uid为null Future _getUserData(User currentUser) async { try { final snapshot = await FirebaseFirestore.instance .collection('users') .doc(currentUser.uid) .get(); if (snapshot.exists) { setState(() { name = snapshot.data()!['Navn']; }); } else { setState(() { name = 'Unknown User'; }); } } catch (e) { // 处理Firestore查询异常 setState(() { name = 'Failed to load name'; }); print('Error fetching user data: $e'); } } @override Widget build(BuildContext context) { var appBarHeight = kToolbarHeight; return Scaffold( key: scaffoldkey, resizeToAvoidBottomInset: false, appBar: AppBar( backgroundColor: const Color.fromRGBO(119, 221, 167, 1), title: const Text( 'Test', style: TextStyle( fontFamily: 'Poppins', color: Colors.white, fontSize: 22, fontWeight: FontWeight.bold, ), ), centerTitle: true, ), backgroundColor: Colors.white, drawer: Container( padding: EdgeInsets.only(top: appBarHeight + 1), child: Drawer( child: ListView( padding: EdgeInsets.zero, children: [ Padding( padding: const EdgeInsets.all(8.0), child: Text(name ?? 'Guest'), ), const SizedBox(height: 10), ], ), ), ), body: SafeArea( child: GestureDetector( onTap: () => FocusScope.of(context).unfocus(), child: Column( mainAxisSize: MainAxisSize.max, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ const SizedBox(height: 20), Text('Hei, ${name ?? 'Guest'}!', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),), ], ), ), )); } }
额外优化点
- 为
name设置初始加载提示,避免刷新时显示空字符串 - 添加异常捕获,处理Firestore查询失败的情况
- 使用空安全操作符
??,避免name为null时触发错误
内容的提问来源于stack exchange,提问作者Alexander
相关产品推荐
相关产品推荐

