firebase-ios-sdk: FirebaseApp.configure(options: options) not loads data when passing FirebaseOptions
Describe your environment
- Xcode version: 8.3.3
- Firebase SDK version: 4.1.1
- Library version: 4.0.6
- Firebase Product: core
Describe the problem
In my app, I have more targets and configurations which require more GoogleServices-Info.plists. I have them all downloaded from firebase console after registering new apps.
On app launch, I am trying to load FirebaseOptions from plist at file path via FirebaseOptions(contentsOfFile: plistPath). Finding plistPath via Bundle.main.path(forResource: plistName, ofType: "plist") (every plist have different name). Although path to plist is found and init is returning FirebaseOptions instance, returned instance is empty.
FirebaseApp.configure(options: options) is then complaining about not finding plist named GoogleService-Info.plist.
Steps to reproduce:
PlistName is different than GoogleService-Info.
guard let plistPath = Bundle.main.path(forResource: plistName, ofType: "plist") else {
fatalError()
}
guard let options = FirebaseOptions(contentsOfFile: plistPath) else {
fatalError()
}
FirebaseApp.configure(options: options)
About this issue
- Original URL
- State: open
- Created 7 years ago
- Reactions: 13
- Comments: 51 (12 by maintainers)
Please correct me if I am wrong, but for a project with multiple build configs (dev VS prod) and targets (say Pokemon Black VS White), each config / target has its own bundle ID and Google app ID, and thus we have to have different plists for each target.
For a project with single target and multiple configs (dev VS prod), we cannot put the
GoogleService-Info.plistfiles into different folders for each config, because if there are multiple files with the same name for the same target, Xcode randomly picks one into the bundle without keeping the folder structure. I figured it out by unzipping the .ipa file and check out the bundle, seeing all resources files from different source folders got put into just one bundle folder.So, putting
GoogleService-Info.plistfiles into different folders won’t solve the issue, and Firebase has to support loading config plist of different names.I found a solution for myself.
I use only one target and a different .xcconfig files for each environment(dev/stage/prod). So, I store my GoogleService-Info.plist-s as below:
Note: GoogleService-Info.plist-s shouldn’t be marked as a Target Membership in File Inspector.
Add to your .xcconfig files a path to GoogleService-Info.plist files: Dev.xcconfig:
GOOGLESERVICE_INFO_PLIST = ${PROJECT_DIR}/TargetName/Resources/Firebase/dev/GoogleService-Info.plistStage.xcconfig:GOOGLESERVICE_INFO_PLIST = ${PROJECT_DIR}/TargetName/Resources/Firebase/stage/GoogleService-Info.plist…Modify your project Info.plist:
Open Target Build Phases, tap + icon, New Run Script Phase and add the following script:
FirebaseApp.configure()inapplication:didFinishLaunchingWithOptions:.Done!
This is a baffling omission in my opinion. The workaround I’m currently using is having a new Build Phase in my project that copies the appropriate file:
where
BUNDLE_ID_SUFFIXis a user defined variable that differs between build configs. Hope this helps.The plist file must be named GoogleService-Info.plist.
If you have multiple, an option is to put them in different folders.
please reopen this, its better to have different plist files than store same files in different folders
Is there any update on this subject? It’s open since 2017…
There is a warning underneath that section of the Getting Started guide mentioning:
That being said, I agree that we should be fixing Analytics to ensure it can handle runtime configuration changes. We’re going to work with the Analytics team to find an acceptable solution that hopefully won’t risk the integrity of data coming from Analytics.
BTW this is console output after
FirebaseApp.configure(options: options)call.Any updates on changing/setting configuration at runtime? In our product there is ability to switch modes within the same app, so we have to re-configure on a switch.
I’d just like to chime in that we are in the exact same position as others. I don’t think we will be able to migrate our other apps from Fabric to Firebase until there is a resolution here.
We have currently implemented a method that configures Firebase at runtime based on the bundle ID detected at runtime, with multiple config plist files.
For us, losing early analytics is by far preferable to changing our entire environment architecture.
I’d also like to point out the following changes (within the last week) to the documentation:
We were using the default name for production, which made us lose all reporting for other environments. @ryanwilson the following solution for configuration is working for crash-reporting:
@ryanwilson, @paulb777 Is there any plan or timeline for fixing this issue? We are just couple of months away from google analytics service SDKs being sunset (https://support.google.com/firebase/answer/9167112?hl=en). Though as much as we would love to move to firebase, this issue at present is stopping us from completing the migration from google analytics to firebase. If this is not on a list of issues to be fixed, we will start looking for an alternative and migrating data to another service.
I have created following “workaround”. I have 2 plist files, both correctly named GoogleService-Info.plist, but in separated folders - Debug, Release (it has nothing to do with Debug/Release Xcode scheme). Those files are not even referenced in XCode project.
Then I have file GoogleService-Info.plist - which is empty and this file is referenced in XCode. We use fastlane to configure environment (setting API URL and some other properties), and we have added copying of correct file (from appropriate folder) in place of “placeholder” file.
Sure, this only helps when you want to switch file before build - not on runtime. But then you can use simply
FirebaseApp.configure()+1, seeing this issue for ages:
We use two different plist configurations within a single target just to toggle it in runtime between different stages – even in TestFlight where builds can be treated either as for a Sandbox project (for testers in TestFlight) or for a Production project (when the same build goes live to the App Store).
Pls give this a bit of prio to address it already. 🙏
Same issue here, but I can live with losing some analytics. But what I wonder about are the messages shown after that (Xcode, iOS app):
for completeness:
When I step with my debugger over the last line, this gets printed in the console.
optionsis notnil. According to mypodfile.lockFirebase/Core is 5.12.0.According to the “Getting Started” guide at home page. https://firebase.google.com/docs/configure/#use_multiple_projects_in_your_application
But according to reply above from @ryanwilson , there is no workaround at this moment.
Please fix Google Analytics for Firebase uses runtime configuration.
I want to bump this due to the performance aspect of this. Firebase initialization takes around 30 ms on iOS to initialize.
When passing options via constants this can be slashed almost to a half. Firebase is usually initialized in AppDelegate, which is critical for app start time. Reading and parsing XML plist files is very inefficient on the main thread.
I’m using the last version of Firebase and I’m initialising programmatically my configuration without the GoogleService-Info.plist. But now, I’m receiving an error in app initialising about this. Anybody knows how to fix that?
https://twitter.com/steipete/status/1249693487789944832 might help with workarounds.
Very similar issue here, where Analytics prevents us from switching configurations in runtime. Any progress on making Analytics accept dynamic configuration?
@lifely thanks for the update and the clear goal. It’s still an ongoing discussion and I’ll update with more as it progresses, thanks!
@forsen thanks for bringing that to our attention - looks like the line in question is https://github.com/firebase/firebase-ios-sdk/blob/c724f9d1e8c3d2f7a44b8959983e1ebaa3eaa5cb/Firebase/DynamicLinks/FDLURLComponents/FIRDynamicLinkComponentsKeyProvider.m#L29
This can and should be avoided, I’ll file an issue for it separately.
Seems like
Analyticsis not the only module that does not support multipleGoogleService-Info.plistfiles. We use multiple targets, and name the file like this:GoogleService-Info-<target>.plist. This has worked fine for some time, but when we now tried to addDynamicLinksto our project, it insists on loading theAPI KEYfromGoogleService-Info.plist(which doesn’t exist), and completely ignore that we have initialisedFIRAppwith a custom name for the service file.Does that mean we can not use multi config files in our projects (each file for an environment)?
Any update?
@arthurgivigir I fixed this issue with following changes to run script in Build Phases:
/path/to/pods/dir/FirebaseCrashlytics/upload-symbols -gsp /path/to/app/target/GoogleService-Info.plist -p ios /path/to/built_products_dir/target_name.dSYM/Contents/Resources/DWARF/target -valIf you are working on macOS app, then pass
-p macinstead of-p ios. After this my dsym files uploading successfully.@ryanwilson @paulb777 Should we assume that this is not going to be fixed?
@ryanwilson @paulb777 Is there any update that you guys can provide? Or should we consider that this issue is not going to get fixed in time for google analytics sdk being sunset?
Hey @ryanwilson Thanks a lot for providing the update.
Unfortunately, we do not have two different targets. We only have one target (IPA/APK) file which gets generated and has ability to connect to different servers (QA,STG,PROD) and hence we need an ability to switch the instance runtime. We decide where the user is logging in depending on the username and server specifier that they enter. It is strange since Firebase at core supports switching instance runtime. But just google analytics as a part of firebase does not support.
So we are not in a hurry since google analytics is not gonna be deprecated till next year. But do you think there would be a solution before that?
Once again, appreciate all the help.
Regards, Bhavik
I’d like to bump this, the issue seems to have been open a year ago.
We’re also struggling with this, we might implement the
build-scriptsolution but imho this isn’t a good solution at all.Our goal is to be able to switch environment at runtime and even though the api looks like it’s build for it
FirebaseApp.configurewith multipleFIRAppinstances,Analyticsuse a static approach.The best case scenario I would love to see:
were the static helper would simply call
I understand their could be “lost” analytics, but that’s just our responsibility to call configuration as soon as possible.
And is there any reason why it should be named exactly like that? The init(contentsOfFile:) could parse any plist, if given in a right path.