SwiftUI集成Firebase时用户数据显示延迟问题求助
SwiftUI + Firebase 重启应用后用户名显示延迟问题解决
问题根源
重启应用时,FirebaseAuthManager的checkUserStatus方法会先将userStatus设为.authenticated,再异步拉取Firestore中的用户信息。此时Dashboard页面已经加载,但user对象还是初始的空值,直到Firestore请求完成才会更新,导致用户名显示延迟。
解决方案
方案一:等待用户信息加载完成后再切换页面
调整checkUserStatus的逻辑,先完成用户信息的拉取,再更新userStatus,确保Dashboard加载时数据已经就绪。
- 修改
checkUserStatus方法:
extension FirebaseAuthManager { func checkUserStatus() { Task { @MainActor in let listener = Auth.auth().addStateDidChangeListener { [weak self] _, user in guard let self = self, let user = user else { self?.userStatus = .notAuthenticated return } // 先拉取用户信息,再切换状态 Task { do { try await self.fetchUserInfo(userID: user.uid) self.userStatus = .authenticated } catch { print("获取用户信息失败: \(error)") // 拉取失败仍可进入Dashboard,显示默认值或提示 self.userStatus = .authenticated } } } Auth.auth().removeStateDidChangeListener(listener) } } }
- 恢复
fetchUserInfo为异步await版本,并确保在主线程更新user:
extension FirebaseAuthManager { @MainActor func fetchUserInfo(userID: String) async throws { let reference = Firestore.firestore().collection(userCollection).document(userID) self.user = try await reference.getDocument(as: FirestoreModel.User.self) } }
方案二:在Dashboard中处理加载状态
如果不想等待数据拉取再跳转页面,可以在Dashboard中判断用户数据是否就绪,显示加载占位符直到数据更新。
修改DashboardView的body部分:
struct DashboardView: View { @EnvironmentObject private var authManager: FirebaseAuthManager var body: some View { NavigationView { VStack { // 用户名未加载完成时显示加载状态 if authManager.user.name.firstName.isEmpty { ProgressView("加载中...") } else { Text("Benvenuto " + authManager.user.name.firstName + "!") } } .navigationTitle("Dashboard") .toolbar { ToolbarItem(placement: .navigationBarTrailing) { Button("Esci".uppercased()) { logout() } .font(.callout).bold() } } } } }
额外说明
之前修改fetchUserInfo为闭包版本后,登录时用户名能立即显示,是因为登录流程中可能已经通过signUp或其他逻辑提前设置了user对象;但重启应用时需要重新从Firestore拉取数据,异步请求的延迟就会暴露出来,所以需要针对性处理初始化时的状态流转。
内容的提问来源于stack exchange,提问作者kAiN
相关产品推荐
相关产品推荐

