【问题标题】:Error: `call FirebaseApp.configure() before using Firestore`错误:`在使用 Firestore 之前调用 FirebaseApp.configure()`
【发布时间】:2019-04-27 09:41:38
【问题描述】:

背景资料

我已经开始为一个简单的应用程序开发一个后端,并且我已经设置了一个所有文件都将与之通信的数据库类(名为DBDelegate)。 在我的AppDelegate.swift 我有这个:

static public var dbDelegate:DBDelegate = DBDelegate()

private func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.
    FirebaseApp.configure()
    return true
}

它是static public,所以我可以从其他文件访问dbDelegate

在我的其他文件中,我有以下内容来帮助提高可读性:(因为它是一个将通过引用传递的类)

let dbDelegate = AppDelegate.dbDelegate

在我的DBDelegate 班级:

var db = Firestore.firestore()
init() {
    FirebaseApp.configure()
}

构建和运行

当我构建我的代码时,它构建得很好。

在运行时,应用程序会立即崩溃并显示 SIGABRT。 错误信息是:
Terminating app due to uncaught exception 'FIRAppNotConfiguredException', reason: 'Failed to get FirebaseApp instance. Please call FirebaseApp.configure() before using Firestore'

我尝试过的

  • 我尝试在DBDelegate 类的init 函数上设置断点。它没有到达断点。
  • 我已尝试将所有dbDelegate 变量lazy
    • 我在 AppDelegate 中遇到了编译错误:lazy must not be used on an already-lazy global
    • 其他人的运行时错误:请在使用 Firestore 之前调用 FirebaseApp.configure()。
  • 我尝试了以下方法(在 didFinishLaunchingWithOptions 中分配 dbDelegate):
静态公共 var dbDelegate:DBDelegate! 私有函数应用程序(_应用程序:UIApplication,didFinishLaunchingWithOptions launchOptions [UIApplication.LaunchOptionsKey:Any]?)-> Bool { // 应用程序启动后自定义的覆盖点。 FirebaseApp.configure() dbDelegate = DBDelegate() 返回真 }
  • 我得到编译错误:Static member 'dbDelegate' cannot be used on instance of type 'AppDelegate'

任何帮助都会很棒!

编辑:我找到了一个 janky 解决方案,见下文。

【问题讨论】:

    标签: ios swift firebase google-cloud-firestore


    【解决方案1】:

    首先,我要感谢@DionzB 建议使用单例(我这样做了)。我将在此答案中引用他/她的帖子。

    好的,所以经过一些研究和玩断点后,我发现我的自定义类实际上在 AppDelegate 之前执行。知道了这一点,我在以下行之前创建了一个变量:

    static let shared = FirebaseService()
    

    名字无所谓,因为我/你不会叫它,分配给FirebaseApp.configure()

    FirebaseService 类变为:

    class FirebaseService: NSObject {
        let constantToNeverTouch = FirebaseApp.configure()
        static let shared = FirebaseService()
    
        init() {
        }
    }
    

    接下来,您必须确保 FirebaseApp.configure() 不在您的代码中的其他位置。它也不应该在 AppDelegate 中。拥有多个 FirebaseApp.configure() 会使应用程序崩溃。

    【讨论】:

      【解决方案2】:

      您可以使用 FirebaseApp.configure() 覆盖 AppDelegate init 方法,并确保在创建任何窗口之前加载它。

      override init() {
              FirebaseApp.configure()
      }
      

      【讨论】:

        【解决方案3】:

        最好为 Firebase 创建一个新的单例。

        class FirebaseService: NSObject {
            static let shared = FirebaseService()
        
            init() {
                 FirebaseApp.configure()
            }
        }
        

        然后您可以通过以下方式访问所有内容:

        FirebaseService.shared.methodName
        

        对于在应用程序委托中进行配置,您需要这样称呼它:

        _ = FirebaseService.shared
        

        【讨论】:

        • 感谢您帮助使我的代码更清晰,但我仍然有错误。
        • 不不,您必须使用我的想法而不是您的想法,并且您需要在 App Delegate _ = FirebaseApp.shared 中调用它,正如我告诉您的那样。然后在不同的控制器中,您将再次使用此服务,但每次您必须从共享实例访问方法。
        • 我使用了你的想法,但 super.init() 不起作用,因为我的 DBDelegate 类是根类。你的意思是在 App Delegate 中的 _ = FirebaseService.shared,因为 FirebaseApp 没有共享成员
        • 我删除了super.init()。我说 FirebaseService 我创建的新类不是Firebase 默认类
        • 非常抱歉,但我们的代码似乎仍然无法正常工作。我现在认为这可能是因为在 FirebaseApp 有机会完全 init() 之前执行了命令
        【解决方案4】:

        您的代码顺序可能有误。确保您的窗口代码放在 firebaseApp.configure 之后而不是之前。我遇到了同样的崩溃,直到我在 firebaseApp.configure 连接之后简单地放置了我的窗口创建代码:(window = UIWindow(frame: UIScreen.main.bounds), etc)。只是交换了它们的位置:

            FirebaseApp.configure()
            let db = Firestore.firestore()
            let settings =  db.settings
            settings.areTimestampsInSnapshotsEnabled = true
            db.settings = settings
        
            window = UIWindow(frame: UIScreen.main.bounds)
            window?.rootViewController = HomeController()
            window?.makeKeyAndVisible()
        

        【讨论】:

          【解决方案5】:

          我遇到了同样的问题,因为我的 pod 版本太旧了。所以解决方案是

          1. 使用命令pod --version检查您的 pod
            如果 pod 版本旧或不同,CocoaPods 需要更新。使用评论sudo gem install CocoaPods

          2. 完成后,您需要再次检查您的 pod,使用命令 pod --version 确保您的 pod 版本已升级

          3. cd 到你的项目目录然后使用命令pod deintegrate
            命令完成后使用pod install

          4. 打开您的项目工作区,构建并运行

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2021-11-06
            • 1970-01-01
            • 2012-05-02
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多