Flutter应用无法实时获取Firebase实时数据库更新数据的问题
问题原因分析
- 单次读取而非实时监听:你使用的
userRef.once()是单次读取数据库数据的方法,只会在调用时获取一次数据。当用户信息更新后,数据库发生变化,但这个方法不会自动重新执行,导致userModelCurrentInfo始终存储旧数据。 - UI未触发重建:即使
userModelCurrentInfo被更新,你没有通知Flutter框架重新构建UI,页面自然不会展示新数据。切换标签页再返回时,页面会重新执行初始化逻辑(比如initState),再次调用读取方法才拿到新数据。
解决方案
1. 改用实时监听取代单次读取
Firebase Realtime Database提供onValue监听,能实时接收数据变化的回调。在页面状态类中设置监听,数据更新时自动触发UI刷新。
2. 用setState通知UI重建
在监听回调中调用setState,让Flutter重新构建页面,展示最新的用户信息。
3. 取消监听避免内存泄漏
在页面销毁时取消订阅监听,防止内存泄漏。
修改后的代码示例
状态类中的监听与UI更新
假设你的个人资料页是StatefulWidget,修改其状态类代码:
import 'package:firebase_auth/firebase_auth.dart'; import 'package:firebase_database/firebase_database.dart'; import 'package:flutter/material.dart'; class ProfilePage extends StatefulWidget { const ProfilePage({super.key}); @override State<ProfilePage> createState() => _ProfilePageState(); } class _ProfilePageState extends State<ProfilePage> { UserModel? userModelCurrentInfo; late DatabaseReference _userRef; late StreamSubscription<DatabaseEvent> _userSubscription; @override void initState() { super.initState(); _setupUserRealtimeListener(); } void _setupUserRealtimeListener() { final currentFirebaseUser = FirebaseAuth.instance.currentUser; if (currentFirebaseUser == null) return; _userRef = FirebaseDatabase.instance .ref() .child("passengers") .child(currentFirebaseUser.uid); // 实时监听用户数据变化 _userSubscription = _userRef.onValue.listen((DatabaseEvent event) { final snapshot = event.snapshot; if (snapshot.value != null) { setState(() { userModelCurrentInfo = UserModel.fromSnapshot(snapshot); }); } }); } @override void dispose() { // 页面销毁时取消监听 _userSubscription.cancel(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( drawer: Drawer( child: ListView( children: [ if (userModelCurrentInfo != null) UserAccountsDrawerHeader( decoration: const BoxDecoration( color: Color(0xFFFED90F), ), accountName: Text( userModelCurrentInfo!.first_name ?? "", style: const TextStyle( color: Colors.white, fontSize: 15, fontFamily: "Montserrat", fontWeight: FontWeight.w600, ), ), accountEmail: Text(userModelCurrentInfo!.email ?? ""), ), // 其他Drawer选项 ], ), ), // 页面其他内容 ); } }
保留原用户模型代码
你的UserModel代码无需修改,确保能正确从DataSnapshot解析数据即可。
额外说明
- 如果项目使用全局状态管理(如Provider、Riverpod),可以将用户信息放在全局状态中,监听数据变化后更新全局状态,所有依赖该状态的页面都会自动刷新。
- 确保用户更新数据后,数据库字段与
UserModel的字段完全匹配,避免解析错误导致数据不更新。
内容的提问来源于stack exchange,提问作者annyeongk
相关产品推荐
相关产品推荐

