Reputation: 479
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()
}
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'
DBDelegate
class. It does not reach the breakpoint.dbDelegate
variables lazy
:
lazy must not be used on an already-lazy global
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 }
Static member 'dbDelegate' cannot be used on instance of type 'AppDelegate'
Any help would be great!
Edit: I found a janky solution, see below.
Upvotes: 2
Views: 6403
Reputation: 1
I got the same issue because my pod version it old. So the solution is
Check your pods by using command pod --version
If pod the version is old or not the same, CocoaPods needs to update. Use comment sudo gem install CocoaPods
After it has completed you need to check your pods again use command pod --version
make sure your pod version is upgraded
cd
to your project directory then use command pod deintegrate
After the command completed then use pod install
Open your project workspace, build & run
Upvotes: 0
Reputation: 49
You can override the AppDelegate init method with FirebaseApp.configure() and make sure it loads before any windows are created.
override init() {
FirebaseApp.configure()
}
Upvotes: 3
Reputation: 71
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()
Upvotes: 2
Reputation: 479
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.
Upvotes: 4
Reputation: 1507
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
Upvotes: 2