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

已实现SessionAuth ViewModel,为何ContentView无法显示Firestore数据?

解决Firestore用户数据无法在SwiftUI视图中显示的问题

以下是针对你代码问题的排查和修复方案:

1. 确保fetchUser方法被触发

当前SessionAuth的初始化方法仅调用了checkLoginStatus,但没有在确认用户登录后触发fetchUser。需要在登录状态验证逻辑中添加数据获取调用:

func checkLoginStatus() {
    // 监听Auth状态变化,用户登录时自动拉取数据
    Auth.auth().addStateDidChangeListener { [weak self] auth, user in
        guard let self = self else { return }
        self.isLoggedIn = user != nil
        if self.isLoggedIn {
            self.fetchUser() // 用户登录状态确认后触发数据获取
        } else {
            self.user = nil
        }
    }
}

如果checkLoginStatus是一次性检查当前用户,也需要补充调用:

func checkLoginStatus() {
    isLoggedIn = Auth.auth().currentUser != nil
    if isLoggedIn {
        fetchUser()
    }
}

2. 切换到主线程更新视图状态

Firestore的回调默认在后台线程执行,直接更新@Published属性可能无法触发SwiftUI视图刷新,必须切换到主线程:

func fetchUser() {
    guard let uid = Auth.auth().currentUser?.uid else { return }
    db.collection("users").document(uid).getDocument { [weak self] document, error in
        // 强制切换到主线程更新UI相关属性
        DispatchQueue.main.async {
            guard let self = self else { return }
            if let error = error {
                print("获取用户数据失败: \(error.localizedDescription)")
                self.showError = true
                return
            }
            guard let document = document, document.exists else {
                print("用户文档不存在")
                return
            }
            do {
                let user = try document.data(as: User.self)
                self.user = user
                print("数据已加载")
            } catch {
                print("解析用户数据失败: \(error.localizedDescription)")
                self.showError = true
            }
        }
    }
}

3. 确认User模型的Codable实现正确

确保User结构体遵循Codable协议,且字段与Firestore文档完全匹配(包括大小写、字段名),必要时添加CodingKeys映射:

import FirebaseFirestoreSwift

struct User: Codable, Identifiable {
    var id: String
    var name: String
    // 其他自定义字段...
    
    // 如果Firestore字段名与属性名不一致,添加映射
    enum CodingKeys: String, CodingKey {
        case id
        case name = "user_name" // 示例:Firestore字段为user_name时的映射
    }
}

注意:必须导入FirebaseFirestoreSwift库才能使用document.data(as:)方法。

4. 正确注入EnvironmentObject

在App入口或父视图中,使用@StateObject持有SessionAuth实例,并通过environmentObject注入到视图环境中,确保整个视图树共享同一个实例:

@main
struct YourApp: App {
    @StateObject private var sessionAuth = SessionAuth()
    
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(sessionAuth)
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 14:20:23