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

SwiftUI+Firebase登录功能用户会话校验异常求助

解决Firebase Auth用户会话始终非nil的问题

问题根源

  1. Firebase Auth默认开启会话持久化,只要曾经成功注册/登录过用户,Auth.auth().currentUser就会一直保留该用户对象,除非主动登出或清除App数据。
  2. 你的AuthViewModel仅在初始化时读取一次currentUser,没有监听Auth状态的实时变化,后续状态变更(比如登出)无法同步到userSession。
  3. login方法是空实现,登录成功后未更新userSession;同时缺少登出方法,无法主动将userSession重置为nil。

解决步骤

  1. 清除测试会话:在模拟器或真机上删除App,清除之前保存的用户会话,确保初始状态下currentUser为nil。
  2. 添加Auth状态监听:通过addStateDidChangeListener实时监听用户登录状态,自动同步userSession。
  3. 完善登录与登出逻辑:补全登录方法的实现,添加登出方法重置会话状态。
  4. 修复预览环境:在预览中注入AuthViewModel实例,保证预览正常运行。

修改后的代码

AuthViewModel.swift

import SwiftUI
import Firebase

class AuthViewModel: ObservableObject {
    @Published var userSession: FirebaseAuth.User?
    
    init() {
        // 实时监听Auth状态变化,自动更新userSession
        Auth.auth().addStateDidChangeListener { [weak self] auth, user in
            self?.userSession = user
            print("DEBUG: User session updated to \(self?.userSession)")
        }
    }
    
    func login(withEmail email: String, password: String) {
        print("DEBUG: login with email \(email)")
        
        Auth.auth().signIn(withEmail: email, password: password) { [weak self] result, error in
            if let error = error {
                print("debug: failed to login \(error.localizedDescription)")
                return
            }
            
            guard let user = result?.user else { return }
            self?.userSession = user
            print("debug: logged in user success")
        }
    }
    
    func register(withEmail email: String, password: String, username: String, firstName: String, lastName: String, occupation: String) {
        Auth.auth().createUser(withEmail: email, password: password) { [weak self] result, error in
            if let error = error {
                print("debug: failed to register \(error.localizedDescription)")
                return
            }
            
            guard let user = result?.user else { return }
            self?.userSession = user
            
            print("debug: registered user success")
            print("debug: user is \(self?.userSession)")
        }
    }
    
    // 新增登出方法
    func logout() {
        do {
            try Auth.auth().signOut()
            print("debug: logged out success")
        } catch {
            print("debug: failed to logout \(error.localizedDescription)")
        }
    }
}

ContentView.swift(仅修改预览部分)

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        NavigationView{
            ContentView()
                .environmentObject(AuthViewModel()) // 注入ViewModel实例
        }
    }
}

说明

  • 现在App启动时会自动同步当前Auth状态,登录、注册、登出操作都会实时更新userSession,页面会自动切换。
  • 测试时先删除App清除旧会话,重新运行就能看到初始状态显示登录页面;登录/注册后会自动跳转到主界面;调用logout方法会回到登录页面。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 06:30:32