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

Flutter应用无法实时获取Firebase实时数据库更新数据的问题

问题原因分析
  1. 单次读取而非实时监听:你使用的userRef.once()是单次读取数据库数据的方法,只会在调用时获取一次数据。当用户信息更新后,数据库发生变化,但这个方法不会自动重新执行,导致userModelCurrentInfo始终存储旧数据。
  2. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 14:15:41