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

SwiftUI中FirebaseAuth适配iOS17 @Observable模式报错求助

解决iOS17 @Observable模式下FirebaseAuth初始化顺序错误问题

问题重现

将原有基于ObservableObject/EnvironmentObject的FirebaseAuth代码迁移至iOS17新的@Observable模式时,出现以下运行时错误:

Thread 1: "The default FirebaseApp instance must be configured before the default Authinstance can be initialized. One way to ensure this is to call FirebaseApp.configure() in the App Delegate's application(_:didFinishLaunchingWithOptions:) (or the @main struct's initializer in SwiftUI)."

旧代码(正常运行):

class Authentication : ObservableObject { ... } 

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

@main
struct RApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
    @StateObject var authentication = Authentication()

    var body: some Scene {
        WindowGroup {
            RootView()
                .environmentObject(authentication)
                .preferredColorScheme(.dark)
        }
    }
}

新代码(报错):

@Observable
class Authentication { ... }

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

@main
struct RApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
    
    @State private var authentication: Authentication = Authentication()

    var body: some Scene {
        WindowGroup {
            RootView()
                .environment(authentication)
                .preferredColorScheme(.dark)
        }
    }
}

原因分析

旧代码中@StateObject的初始化是懒加载的,会在首次需要使用时才创建实例,此时AppDelegate已经完成FirebaseApp.configure()的调用。而新代码中使用@State直接初始化Authentication时,实例会在RApp结构体初始化时就被创建——这个时机早于AppDelegate的didFinishLaunchingWithOptions方法执行,导致Firebase还未配置就初始化了Auth相关逻辑,触发错误。

解决方案

方案1:将Firebase配置移至App结构体的初始化器

直接在@main的App结构体初始化时调用FirebaseApp.configure(),确保在Authentication实例化前完成配置:

@Observable
class Authentication { ... }

@main
struct RApp: App {
    private var authentication: Authentication
    
    init() {
        FirebaseApp.configure()
        self.authentication = Authentication()
    }

    var body: some Scene {
        WindowGroup {
            RootView()
                .environment(authentication)
                .preferredColorScheme(.dark)
        }
    }
}

注:此方案可以移除AppDelegate,简化代码结构。

方案2:用lazy延迟初始化Authentication

保持AppDelegate的配置逻辑,通过lazy让Authentication在首次使用时才初始化,此时Firebase已经完成配置:

@Observable
class Authentication { ... }

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

@main
struct RApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
    @State private lazy var authentication = Authentication()

    var body: some Scene {
        WindowGroup {
            RootView()
                .environment(authentication)
                .preferredColorScheme(.dark)
        }
    }
}

方案3:通过@State的初始化闭包延迟创建实例

利用@State的闭包初始化特性,确保Firebase配置完成后再创建Authentication:

@Observable
class Authentication { ... }

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

@main
struct RApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
    @State private var authentication: Authentication = {
        return Authentication()
    }()

    var body: some Scene {
        WindowGroup {
            RootView()
                .environment(authentication)
                .preferredColorScheme(.dark)
        }
    }
}

注:此方案依赖AppDelegate的执行顺序,若后续iOS版本调整启动流程可能存在风险,优先推荐方案1或2。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 06:03:24