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
相关产品推荐
相关产品推荐

