Search code examples
iosswiftwidgetcrashlyticsfirebase-analytics

Can you use Firebase from an iOS widget when it's already used in the main application?


I have firebase Analytics and Crashlytics setup in the target for my main application: all the libraries, GoogleService-Info.plist, Firebase.h,... all of it. Now I've added a widget and it's actually able to import the various libraries

import FirebaseApp

but then once I use it

FirebaseApp.configure()

I get a build failure with

Undefined symbols for architecture arm64: "_OBJC_CLASS_$FIRApp" ...

I assume I'm able to access the libraries because of the Firebase.h file. I know I can't access the libraries because the widget is running in a separate process from the app, which contains the libraries.

I was able to get this partially working by adding an embedded framework to my project that wraps the firebase libraries, then using that from the widget, but that causes intermittent runtime crashes in the main app with [FBLPromise HTTPBody]: unrecognized selector. According to Firebase's docs this is expected undefined behavior. In addition with this approach, I get console logs about firebase libraries being implemented in 2 places.

From here I tried creating a separate static library that wraps the firebase libraries I need, then surfaces API to the app and the widget, but build errors from the main app about the static library trying to access firbase libraries.

Has anyone managed to find a way to use firebase, specifically Analytics, from both the main app and widget of the same project?

I will say, I saw a hack someone did where they actually added an extension to FBLPromise and implemented the unrecognized selectors with empty implementations, which I thought was awful, but am now considering :/

Edit: I'm not using Cocoapods or SPM, so this is all manual, unfortunately.


Solution

  • I ended up solving this by using a separate embedded framework that wraps the firebase libraries, removing the libraries from the main app, then accessing them only through this separate framework. One issue came up, which is that FirebasePerformance cannot be used from an extension-safe framework, so I didn't do anything with it in the framework, and configured it in the main app before calling configure() on the firebase wrapper.