Firebase Auth在VisionOS SwiftUI应用重启后自动登出问题求助
VisionOS应用升级Firebase后重启自动登出
我的VisionOS应用原本运行正常,为适配VisionOS将Firebase从8.x版本升级到10.20.0(使用SPM)后,出现了每次重启都会自动登出的问题。相关代码如下:
appnameApp
@StateObject private var store = Store() init() { // 初始化Firebase FirebaseApp.configure() } var body: some Scene { WindowGroup { ContentView() .environmentObject(store) } } }
ContentView
@EnvironmentObject var store: Store switch store.userAuthState { case .signedIn: AppTabView() .environmentObject(store) case .signedOut: LoginView() case .undefined: LoadingView() } enum UserAuthenticationState { case undefined, signedOut, signedIn }
Store Object
class Store : ObservableObject { private var db = Firestore.firestore() // 会话属性 @Published var userAuthState: UserAuthenticationState = .signedOut @Published var session: User? @Published var isEmailVerified = false @Published var userEmail: String? init () { handle = Auth.auth().addStateDidChangeListener { [self] (auth, user) in if let user = user { print("StateDidChangeListener") self.userEmail = user.email self.session = user if let u = auth.currentUser { self.isEmailVerified = u.isEmailVerified } if self.profile == nil { self.fetchProfile(uid: user.uid) } } else { self.session = nil self.userAuthState = .signedOut } } } deinit { if let handle = handle { Auth.auth().removeStateDidChangeListener(handle) } } }
目标平台:VisionOS
Firebase版本:10.20.0(SPM)
问题原因及修复方案
核心问题分析
- 初始化顺序错误:
@StateObject的Store会在appnameApp的init()之前完成初始化,导致Firebase还未配置就启动了Auth状态监听,无法读取本地缓存的用户会话。 - 状态更新遗漏:当Auth回调检测到已登录用户时,没有将
userAuthState设置为.signedIn,初始状态又是.signedOut,导致UI始终显示登录页。
修复步骤
1. 调整Firebase与Store的初始化顺序
修改appnameApp,确保先完成Firebase配置,再创建Store实例:
@StateObject private var store: Store init() { FirebaseApp.configure() self.store = Store() } var body: some Scene { WindowGroup { ContentView() .environmentObject(store) } }
2. 完善Auth状态回调的状态更新
在Store的监听回调中,当检测到用户存在时,明确设置登录状态:
init () { handle = Auth.auth().addStateDidChangeListener { [self] (auth, user) in if let user = user { print("StateDidChangeListener") self.userEmail = user.email self.session = user if let u = auth.currentUser { self.isEmailVerified = u.isEmailVerified } // 关键:更新为已登录状态 self.userAuthState = .signedIn if self.profile == nil { self.fetchProfile(uid: user.uid) } } else { self.session = nil self.userAuthState = .signedOut } } }
3. 显式设置Auth持久化策略(可选但推荐)
在Store的init中添加持久化设置,确保VisionOS上会话缓存生效:
init () { // 先设置持久化 Auth.auth().setPersistence(.local) { error in if let error = error { print("持久化设置失败:\(error.localizedDescription)") } } // 再启动状态监听 handle = Auth.auth().addStateDidChangeListener { [self] (auth, user) in // 原有回调逻辑... } }
4. 验证网络权限配置
确保Info.plist中包含Firebase所需的网络权限,避免会话验证失败:
<key>NSAppTransportSecurity</key> <dict> <key>NSExceptionDomains</key> <dict> <key>firebaseio.com</key> <dict> <key>NSIncludesSubdomains</key> <true/> <key>NSAllowsArbitraryLoads</key> <true/> </dict> </dict> </dict>
完成以上调整后,重启应用时Firebase Auth会正确读取本地缓存的用户会话,状态回调会触发并更新UI状态,解决自动登出问题。
内容的提问来源于stack exchange,提问作者RileyDev
相关产品推荐
相关产品推荐

