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

