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

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直接返回;且登录成功后没有触发重新获取用户数据的逻辑。

解决步骤:

  1. 给UserDataFetch添加手动刷新方法
    在UserDataFetch类中新增公开方法,用于主动触发用户数据获取:

    class UserDataFetch: ObservableObject {
        // 原有代码保留...
        
        // 添加刷新方法
        func refreshCurrentUser() {
            fetchCurrentUser()
        }
    }
    
  2. 登录成功后调用刷新方法
    在视图中持有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()
            }
        }
    }
    
  3. 优化监听器逻辑(可选)
    如果需要实时监听用户数据变化,避免重复添加监听器,可保存监听器引用并在刷新时移除旧监听器:

    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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 23:50:34