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

SwiftUI对接Firebase登出再登录找不到UserDataManager的ObservableObject错误如何解决

SwiftUI 接入Firebase登出后重登提示UserDataManager未注入错误修复

我目前正在开发一款从Firebase拉取数据的App,需要制作个人资料卡片展示与user.uid关联的用户数据,但是账号登出后重新登录时会抛出如下错误:

Fatal error: No ObservableObject of type UserDataManager found. A View.environmentObject(_:) for UserDataManager may be missing as an ancestor of this view.

关联代码

App文件代码

import SwiftUI
import Firebase

@main
struct Darbo_ManijaApp: App {

@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

var body: some Scene {
    WindowGroup {
        let viewModel = AppViewModel()
        let userdataManager = UserDataManager()
        ContentView()
            .environmentObject(viewModel)
            .environmentObject(userdataManager)
    }
}
}

class AppDelegate: NSObject, UIApplicationDelegate {

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
    FirebaseApp.configure()
    return true
}

}

UserDataManager文件代码

import Foundation
import Firebase

class UserDataManager: ObservableObject {

@Published var userFirstName: String = ""

init() {
    fetchUser()
}

func fetchUser() {
    let db = Firestore.firestore()
    let userID = Auth.auth().currentUser?.uid ?? "Not Found"
    
    db.collection("users").document(userID)
        .addSnapshotListener { documentSnapshot, error in
            guard let document = documentSnapshot else {
                print("Error fetching document: \(error!)")
                return
            }
            
            guard let data = document.data() else {
                print("Document data was empty.")
                return
            }
            print("Fetched Data")
            self.userFirstName = data["firstname"] as? String ?? ""
        }
}
}

ContentView文件代码

struct ContentView: View {

@EnvironmentObject var userdataManager: UserDataManager
@EnvironmentObject var viewModel : AppViewModel
var body: some View {
    if viewModel.isSignedIn {
        
        UIKitTabView {
            JobListView().environmentObject(userdataManager).environmentObject(viewModel).tab(title: "Pradžia", image: "network")
            JobListView().tab(title: "Žinutės", image: "message")
            LoginView().tab(title: "Paskyra", image: "person")
            
        }
    } else {
        LoginView()
    }
}
}

JobListView代码

struct JobListView: View {

@EnvironmentObject var viewModel : AppViewModel
@EnvironmentObject var userdataManager: UserDataManager
let firebaseUserID = Auth.auth().currentUser?.uid ?? "Not Found"

var body: some View {
    
    NavigationView{
        ScrollView{
            VStack(alignment: .leading, spacing: 0) {
                Text("Test")
                Text("User ID is: \(firebaseUserID)")
                
                Text("My Name is: \(userdataManager.userFirstName)")

                ForEach(jobData, id: \.id) { job in
                    JobCardView(job: job)
                }
            }
            .frame(minWidth: 0,
                   maxWidth: .infinity,
                   minHeight: 0,
                   maxHeight: .infinity)
            .padding()
        }
        .navigationBarItems(leading:
                                HStack{
            Image("TextDM")
                .resizable()
                .scaledToFit()
                .frame(height: 15)
        })
        .navigationBarItems(trailing:
                                HStack{
            
            Button(action: {
                viewModel.signOut()
            }) {
                Image(systemName: "person.crop.circle")
                    .accentColor(Color.primary)
                
            }
        })
        
        .navigationBarTitle("")
        .navigationBarTitleDisplayMode(.inline)
        .onAppear(){
            userdataManager.fetchUser()
        }
    }
    .environmentObject(userdataManager)
    .environmentObject(viewModel)
}
}

问题排查与解决

一开始以为是ContentView调用TabBarItem时没有注入对象,补充第一个标签页的注入后问题仍然存在,报错出现在JobListView中Text("My Name is: \(userdataManager.userFirstName)")的位置。App首次启动登录时运行正常、登出逻辑也正常,只有登出后重新登录会触发报错。

最终问题定位为自定义TabView的注入规则问题:自定义TabView的每一个标签页都是独立的视图链路,需要给所有标签页都注入对应的ObservableObjects,仅给单个标签页注入无法覆盖其他页面的调用场景。修改ContentView中TabView的代码即可解决:

UIKitTabView {
    JobListView().environmentObject(userdataManager).environmentObject(viewModel).tab(title: "Pradžia", image: "network")
    // 给第二个标签页补充注入
    JobListView().environmentObject(userdataManager).environmentObject(viewModel).tab(title: "Žinutės", image: "message")
    // 给第三个标签页补充注入
    LoginView().environmentObject(userdataManager).environmentObject(viewModel).tab(title: "Paskyra", image: "person")
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 10:57:01