问题
Background Info
I have started developing a backend for an simple App, and I have set up a database class (named DBDelegate) that all the files will communicate with.
In my AppDelegate.swift I have this:
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
}
Its a static public so I can access the dbDelegate from other files.
In my other files, I have the following to help readability: (because it is a class it will pass by reference)
let dbDelegate = AppDelegate.dbDelegate
In my DBDelegate class:
var db = Firestore.firestore()
init() {
FirebaseApp.configure()
}
Building and Running
When I build my code, it builds fine.
On run, the app promptly crashes with SIGABRT.
The error message is:Terminating app due to uncaught exception 'FIRAppNotConfiguredException', reason: 'Failed to get FirebaseApp instance. Please call FirebaseApp.configure() before using Firestore'
What I have tried
- I have tried putting a breakpoint on the init function in the
DBDelegateclass. It does not reach the breakpoint. - I have tried making the all the
dbDelegatevariableslazy:- I got a compile error for the one in AppDelegate:
lazy must not be used on an already-lazy global - Runtime errors for others: please call FirebaseApp.configure() before using Firestore.
- I got a compile error for the one in AppDelegate:
- I have tried the following (assigning dbDelegate in didFinishLaunchingWithOptions):
static public var dbDelegate:DBDelegate!
private func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
FirebaseApp.configure()
dbDelegate = DBDelegate()
return true
}
- I get Compile error:
Static member 'dbDelegate' cannot be used on instance of type 'AppDelegate'
Any help would be great!
Edit: I found a janky solution, see below.
回答1:
It would be better to create a new singleton for Firebase.
class FirebaseService: NSObject {
static let shared = FirebaseService()
init() {
FirebaseApp.configure()
}
}
Then you can access everything via shared like:
FirebaseService.shared.methodName
For configuring in app delegate you would need to call it like:
_ = FirebaseService.shared
回答2:
Firstly, I would like to thank @DionzB for suggesting using singletons (which I did). I will reference his/her post in this answer.
Ok, so after some research and playing with breakpoints, I found that my custom class actually executes before the AppDelegate. Knowing such, I created a variable before the following line:
static let shared = FirebaseService()
the name does not matter, because I/you will not call it, and assign it to FirebaseApp.configure()
The FirebaseService class becomes:
class FirebaseService: NSObject {
let constantToNeverTouch = FirebaseApp.configure()
static let shared = FirebaseService()
init() {
}
}
Next, you must make sure that FirebaseApp.configure() is no where else in your code. It should not be in the AppDelegate either. Having multiple FirebaseApp.configure()'s crashes the app.
回答3:
You can override the AppDelegate init method with FirebaseApp.configure() and make sure it loads before any windows are created.
override init() {
FirebaseApp.configure()
}
回答4:
Chances are your code are in the wrong order. Make sure your window code are put AFTER the firebaseApp.configure and not before. I was getting the same crash until I simply placed my window creation codes: (window = UIWindow(frame: UIScreen.main.bounds), etc) after the firebaseApp.configure connection .Just swapped their placement:
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:
let dbDelegate = AppDelegate.dbDelegate
In your DBDelegate class:
var db : Firestore?
init() {
FirebaseApp.configure()
db = Firestore.firestore()
}
来源:https://stackoverflow.com/questions/53469351/error-call-firebaseapp-configure-before-using-firestore