SwiftUI+Firebase登录后无法获取Firestore用户数据,需重启应用
SwiftUI + Firestore 登录后无法实时获取用户数据问题
我是SwiftUI新手,正在练习使用Firebase Firestore。目前遇到的问题是:用户登录后,代码无法从Firestore数据库中获取用户的姓名、邮箱及积分等数据,除非用户强制关闭并重新打开应用。
UserDataFetch.swift
import Foundation import FirebaseAuth import FirebaseFirestore struct User { let uid, firstName, lastName, email: String let points: Int } class UserDataFetch: ObservableObject { @Published var uname: User? init() { fetchCurrentUser() } private func fetchCurrentUser() { guard let usID = Auth.auth().currentUser?.uid else { return } Firestore.firestore().collection("users").document(usID).addSnapshotListener { snapshot, error in if let error = error { print("Failed to fetch", error) return } guard let data = snapshot?.data() else { return } let uid = data["uid"] as? String ?? "" let firstName = data["firstName"] as? String ?? "" let lastName = data["lastName"] as? String ?? "" let points = data["points"] as? Int ?? 0 let email = data["email"] as? String ?? "" self.uname = User(uid: uid, firstName: firstName, lastName: lastName, email: email, points: points) } } }
登录函数代码
使用@AppStorage("uid") var userID = ""存储和检查用户登录状态:
func loginUser() { Auth.auth().signIn(withEmail: email, password: password) { authResult, error in if let error = error { print(error) return } if let authResult = authResult { print(authResult.user.uid) userID = authResult.user.uid } } }
问题原因及解决办法
问题核心在于:UserDataFetch初始化时用户未完成登录,Auth.auth().currentUser为nil导致fetchCurrentUser直接返回;且登录成功后没有触发重新获取用户数据的逻辑。
解决步骤:
给
UserDataFetch添加手动刷新方法
在UserDataFetch类中新增公开方法,用于主动触发用户数据获取:class UserDataFetch: ObservableObject { // 原有代码保留... // 添加刷新方法 func refreshCurrentUser() { fetchCurrentUser() } }登录成功后调用刷新方法
在视图中持有UserDataFetch实例(通常用@StateObject),登录成功后调用refreshCurrentUser:// 视图内声明 @StateObject var userData = UserDataFetch() @AppStorage("uid") var userID = "" func loginUser() { Auth.auth().signIn(withEmail: email, password: password) { [weak self] authResult, error in guard let self = self else { return } if let error = error { print(error) return } if let authResult = authResult { print(authResult.user.uid) userID = authResult.user.uid // 登录成功后立即刷新用户数据 self.userData.refreshCurrentUser() } } }优化监听器逻辑(可选)
如果需要实时监听用户数据变化,避免重复添加监听器,可保存监听器引用并在刷新时移除旧监听器:class UserDataFetch: ObservableObject { @Published var uname: User? private var listener: ListenerRegistration? // 保存监听器引用 init() { fetchCurrentUser() } private func fetchCurrentUser() { // 先移除旧监听器 listener?.remove() guard let usID = Auth.auth().currentUser?.uid else { uname = nil return } listener = Firestore.firestore().collection("users").document(usID).addSnapshotListener { snapshot, error in // 原有数据解析逻辑保留 } } func refreshCurrentUser() { fetchCurrentUser() } // 对象销毁时移除监听器 deinit { listener?.remove() } }若不需要实时监听,可将
addSnapshotListener替换为getDocument,仅获取一次数据。
内容的提问来源于stack exchange,提问作者Tony Chronic
相关产品推荐
相关产品推荐

