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

Flutter:如何在多个页面高效访问Firebase用户数据

统一管理Firebase当前登录用户数据的实现方案

核心思路

用单例模式封装一个用户管理类,统一处理Firebase用户的登录状态监听、数据获取与缓存。所有页面通过调用这个类的实例获取用户姓名和邮箱,避免重复发起Firebase请求,同时保证数据一致性。

这个类的核心职责:

  • 监听Firebase Auth的登录状态变化,自动同步当前用户数据
  • 缓存已获取的用户姓名、邮箱,避免重复请求
  • 对外提供简洁的接口,让页面快速获取用户信息

代码实现

1. 封装用户管理类(UserManager)

// UserManager.js
import { getAuth, onAuthStateChanged } from "firebase/auth";
import { getFirestore, doc, getDoc } from "firebase/firestore";

class UserManager {
  // 单例实例
  static instance = null;
  // 当前用户缓存数据
  currentUser = {
    displayName: null,
    email: null
  };
  // 初始化标记,避免重复监听
  isInitialized = false;

  constructor() {
    if (!UserManager.instance) {
      UserManager.instance = this;
      this.init();
    }
    return UserManager.instance;
  }

  // 初始化:监听用户登录状态
  init() {
    if (this.isInitialized) return;
    const auth = getAuth();
    onAuthStateChanged(auth, async (user) => {
      if (user) {
        // 优先从Auth获取基础信息,若姓名不存在则从Firestore补充(根据你的存储结构调整)
        this.currentUser.email = user.email;
        this.currentUser.displayName = user.displayName;

        // 如果用户姓名存储在Firestore的users集合中,取消下面注释
        // const db = getFirestore();
        // const userDoc = await getDoc(doc(db, "users", user.uid));
        // if (userDoc.exists()) {
        //   this.currentUser.displayName = userDoc.data().displayName;
        // }
      } else {
        // 用户未登录,清空缓存
        this.currentUser = { displayName: null, email: null };
      }
    });
    this.isInitialized = true;
  }

  // 获取当前用户信息(返回副本,避免外部修改缓存)
  getCurrentUserInfo() {
    return { ...this.currentUser };
  }

  // 手动刷新用户信息(比如用户修改资料后调用)
  async refreshUserInfo() {
    const auth = getAuth();
    const user = auth.currentUser;
    if (!user) return;

    // 重新从Auth获取基础信息
    this.currentUser.email = user.email;
    this.currentUser.displayName = user.displayName;

    // 如果用Firestore存储用户信息,重新获取最新数据
    // const db = getFirestore();
    // const userDoc = await getDoc(doc(db, "users", user.uid));
    // if (userDoc.exists()) {
    //   this.currentUser.displayName = userDoc.data().displayName;
    // }
  }
}

// 导出单例实例
const userManager = new UserManager();
export default userManager;

2. 页面调用示例

在任意需要展示用户信息的页面,直接导入UserManager实例,获取数据后渲染:

// 示例页面:ProfilePage.js
import userManager from "./UserManager";

// 渲染用户信息到页面
function renderUserInfo() {
  const userInfo = userManager.getCurrentUserInfo();
  if (userInfo.displayName && userInfo.email) {
    document.getElementById("user-name").textContent = userInfo.displayName;
    document.getElementById("user-email").textContent = userInfo.email;
  } else {
    // 处理未登录或数据未加载完成的情况
    document.getElementById("user-info").textContent = "请登录";
  }
}

// 页面加载时触发渲染
window.addEventListener("load", renderUserInfo);

其他三个页面的调用方式完全一致,无需重复编写Firebase请求代码。

注意事项

  • 如果你的用户姓名存储在Firestore而非Auth的profile中,取消代码中对应的注释,调整为你的Firestore集合结构
  • 处理数据加载状态:用户刚登录时,Firebase请求可能还未完成,页面要做好loading或空状态处理
  • 当用户修改个人信息后,调用refreshUserInfo()方法更新缓存,保证所有页面数据同步

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 10:02:24