Skip to content

FirebaseApp.configure(options: options) not loads data when passing FirebaseOptions #230

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
ashhanai opened this issue Sep 4, 2017 · 59 comments

Comments

@ashhanai
Copy link

ashhanai commented Sep 4, 2017

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)
@paulb777
Copy link
Member

paulb777 commented Sep 4, 2017

The plist file must be named GoogleService-Info.plist.

If you have multiple, an option is to put them in different folders.

@ashhanai
Copy link
Author

ashhanai commented Sep 4, 2017

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.

@baolocdo
Copy link

baolocdo commented Sep 5, 2017

I don't think it must be named "GoogleService-Info.plist". Can you check whether the plist file is in the correct bundle or linked properly?
Can you double check with the code below?
[[NSDictionary dictionaryWithContentsOfFile:plistPath]

@ashhanai
Copy link
Author

ashhanai commented Sep 5, 2017

[[NSDictionary dictionaryWithContentsOfFile:plistPath] works properly. Now I noticed, that FirebaseOptions init works just fine, but FirebaseApp.configure(options: options) cannot handle the passing options and is trying to find "GoogleService-Info.plist" anyway.

So it is a different issue after all.

@ashhanai ashhanai changed the title FirebaseOptions(contentsOfFile: plistPath) not loads data from plist FirebaseApp.configure(options: options) not loads data when passing FirebaseOptions Sep 5, 2017
@ashhanai
Copy link
Author

ashhanai commented Sep 5, 2017

BTW this is console output after FirebaseApp.configure(options: options) call.

<Error> [Firebase/Core][I-COR000012] Could not locate configuration file: 'GoogleService-Info.plist'.
<Error> [Firebase/Analytics][I-ACS020006] Google App ID from GoogleService-Info.plist is empty. Please, define GOOGLE_APP_ID in GoogleService-Info.plist for Analytics to work reliably.
<Error> [Firebase/Analytics][I-ACS025020] Analytics requires Google App ID from GoogleService-Info.plist. Your data may be lost. Google App ID has been changed. Original, new ID: (nil), 1:625184029135:ios:f8b3e130939c8434

@ryanwilson
Copy link
Member

Currently, Firebase Analytics depends on the GoogleService-Info.plist file internally, so that's the issue you're seeing. It's something we're working on, I don't believe there's a workaround for you unfortunately.

@paulb777
Copy link
Member

paulb777 commented Sep 5, 2017

FirebaseCore is checking for GoogleService-Info.plist by name at https://github.com/firebase/firebase-ios-sdk/blob/master/Firebase/Core/FIROptions.m#L103

@ashhanai
Copy link
Author

ashhanai commented Sep 5, 2017

@paulb777 I believe that this check is executed only when you are loading default plist, than it should be named "GoogleService-Info.plist"

@ryanwilson Ok, thank you for this insight :)

@baolocdo
Copy link

baolocdo commented Sep 6, 2017

If it doesn't pass the Options from the plist, then the options is probably wrong. Did you rename the GoogleService-Info.plist that you downloaded from the Firebase dashboard? Did you see any logs in this init: https://github.com/firebase/firebase-ios-sdk/blob/master/Firebase/Core/FIROptions.m#L206

@baolocdo
Copy link

baolocdo commented Sep 7, 2017

Sorry, I have just noticed the log @ashhanai gave us:

[Firebase/Analytics][I-ACS025020] Analytics requires Google App ID from GoogleService-Info.plist. Your data may be lost. Google App ID has been changed. Original, new ID: (nil), 1:625184029135:ios:f8b3e130939c8434

So it looks like the GoogleService-Info.plist was parsed just fine. There is no problem with Firebase Core.
Now, Analytics has such error message because it requires a static plist file instead of run-time options. We deliberately output the message to let you know that there could be some events very early in the app life cycle that requires the Google App ID, so you potentially miss some data.
In conclusion, we recommend to have a static GoogleService-Info.plist file (https://firebase.google.com/docs/ios/setup)

@tuantmdev
Copy link

Does that mean we can not use multi config files in our projects (each file for an environment)?

@morganchen12
Copy link
Contributor

You can, you just may miss out on very early analytics info.

@morganchen12
Copy link
Contributor

Closing due to inactivity.

@tedgonzalez
Copy link

please reopen this, its better to have different plist files than store same files in different folders

@morganchen12
Copy link
Contributor

@useeless37 you can create FIRApp instances from different plist files. Analytics in particular uses one of a specific name to capture events very early on in the app lifecycle.

@54lihaoxin
Copy link

54lihaoxin commented Nov 1, 2017

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.plist files 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.plist files into different folders won't solve the issue, and Firebase has to support loading config plist of different names.

@morganchen12 morganchen12 reopened this Nov 1, 2017
@sinofool
Copy link

According to the "Getting Started" guide at home page. https://firebase.google.com/docs/configure/#use_multiple_projects_in_your_application

If the builds are part of a single target, the best option is to give both configuration files unique names (e.g. GoogleService-Info-Free.plist and GoogleService-Info-Paid.plist).

But according to reply above from @ryanwilson , there is no workaround at this moment.

Please fix Google Analytics for Firebase uses runtime configuration.

@ryanwilson
Copy link
Member

There is a warning underneath that section of the Getting Started guide mentioning:

Warning: This approach can impact Analytics collection in some circumstances, see the reliable analytics section.

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.

@matelo
Copy link

matelo commented Jan 25, 2018

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()

@mmynarski
Copy link

Little bit more insight on that one. I have project with Firebase and switching names in runtime using FirebaseOptions(contentsOfFile: filePath)

It was working well on Xcode 9.4.1, but after update to Xcode 10 I have an output
FirebaseOptions([Firebase/Analytics][I-ACS025020] Analytics requires Google App ID from GoogleService-Info.plist. Your data may be lost. Google App ID has been changed. Original, new ID:: filePath)

And debugview at firebase panel doesn't even see the device (simulator ¯_(ツ)_/¯)

@lifely
Copy link

lifely commented Nov 19, 2018

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-script solution 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.configure with multiple FIRApp instances, Analytics use a static approach.

The best case scenario I would love to see:

let application = FirebaseApp.configure(options:) -> FirApp
application.analytics.logEvent()

were the static helper would simply call

Analytics {

  static func logEvent() {
   FirebaseApp.defaultApp.analytics.logEvent()
  } 

}

I understand their could be "lost" analytics, but that's just our responsibility to call configuration as soon as possible.

  • There could be an internal pool to store the events otherwise

@forsen
Copy link

forsen commented Nov 22, 2018

Seems like Analytics is not the only module that does not support multiple GoogleService-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 add DynamicLinks to our project, it insists on loading the API KEY from GoogleService-Info.plist (which doesn't exist), and completely ignore that we have initialised FIRApp with a custom name for the service file.

@ryanwilson
Copy link
Member

@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

This can and should be avoided, I'll file an issue for it separately.

@madhuch073
Copy link

@arthurgivigir I am also having same issue.
Did u find any solution ?

@david-var
Copy link

Any updates on runtime configuration?
We are configuring our app on run time, after login, depending on the user type and prod/development env. And facing the same problem as others, so we cant do that at build time.

@schornon
Copy link

schornon commented May 4, 2022

I found a solution for myself.

  1. 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:
    Снимок экрана 2022-05-04 в 09 56 20
    Note: GoogleService-Info.plist-s shouldn't be marked as a Target Membership in File Inspector.

  2. 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.plist
    Stage.xcconfig:
    GOOGLESERVICE_INFO_PLIST = ${PROJECT_DIR}/TargetName/Resources/Firebase/stage/GoogleService-Info.plist
    ...

  3. Modify your project Info.plist:
    Снимок экрана 2022-05-04 в 10 15 29

  4. Open Target Build Phases, tap + icon, New Run Script Phase and add the following script:
    Снимок экрана 2022-05-04 в 10 19 36

# Get a reference to the destination location for the GoogleService-Info.plist
PLIST_DESTINATION=${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app

# Copy plist
echo "Using ${GOOGLESERVICE_INFO_PLIST}"
cp "${GOOGLESERVICE_INFO_PLIST}" "${PLIST_DESTINATION}"
  1. Use FirebaseApp.configure() in application:didFinishLaunchingWithOptions:.

Done!

@david-var
Copy link

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.

@sbhmajd
Copy link

sbhmajd commented Sep 5, 2022

I just did log event successfully in Debug View at firebase console as following:

let options = FirebaseOptions(googleAppID: googleId, gcmSenderID: gcmId) options.apiKey = apiKey options.projectID = projectId options.bundleID = bundleId FirebaseApp.configure(options: options)

Then used Analytics.logEvent to send event with -FIRDebugEnabled and -FIRAnalyticsDebugEnabled in scheme args.

Every thing seems initialized and correctly configured even in Xcode logs, but FirebaseAnalytics logs tell something else 🙃 ?

[FirebaseAnalytics][I-ACS024000] Debug mode is on
[FirebaseAnalytics][I-ACS020006] Google App ID from GoogleService-Info.plist is empty. Please, define GOOGLE_APP_ID in GoogleService-Info.plist for Analytics to work reliably. See https://goo.gl/txkZbE
[FirebaseAnalytics][I-ACS025020] Analytics requires Google App ID from GoogleService-Info.plist. Your data may be lost. Google App ID has been changed. Original, new ID: (nil)
[FirebaseAnalytics][I-ACS023007] Analytics v.9.4.0 started
[FirebaseAnalytics][I-ACS029014] Successfully parsed a configuration.
[FirebaseAnalytics][I-ACS023016] Analytics is ready to receive events

I don't event have GoogleService-Info.plist in the project.

@username0x0a
Copy link

+1, seeing this issue for ages:

10.0.0 - [FirebaseAnalytics][I-ACS020006] Google App ID from GoogleService-Info.plist is empty. Please, define GOOGLE_APP_ID in GoogleService-Info.plist for Analytics to work reliably. See https://goo.gl/txkZbE
10.0.0 - [FirebaseAnalytics][I-ACS025020] Analytics requires Google App ID from GoogleService-Info.plist. Your data may be lost. Google App ID has been changed. Original, new ID: (nil), 1:767925875369:ios:62bc006ed59750a1

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. 🙏

@ghost
Copy link

ghost commented May 25, 2023

Is there any update on this subject? It's open since 2017..

@jozefvodicka
Copy link

Any update?

@mkj-is
Copy link
Contributor

mkj-is commented Dec 4, 2023

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.

@paulb777
Copy link
Member

paulb777 commented Dec 5, 2023

Thanks @mkj-is Can you show the Instruments logs where you measured the slow plist reading and parsing?

@bluerainxty
Copy link

Any update?

@hn-n
Copy link

hn-n commented May 21, 2024

any update ?

@mkj-is
Copy link
Contributor

mkj-is commented May 21, 2024

@paulb777 We added telemetry to measure Firebase initialization (FirebaseApp.configure()) call in production, as we are focused on improving app start time as much as possible.

  • 130 ms (90th percentile, tvOS – basically equal to slowest device, Apple TV HD)
  • 33 ms (50th percentile, tvOS)
  • 100 ms (90th percentile, iOS – our device composition has large amount of older devices)
  • 56 ms (50th percentile, iOS)

We have these dependencies and we link Firebase statically. We are not leveraging many of these sub-dependencies. Most of them are transitive dependecies of FirebasePerformance or Crashlytics.

  • FirebaseABTesting (10.22.0)
  • FirebaseAnalytics (10.22.0)
  • FirebaseAnalytics/AdIdSupport (10.22.0)
  • FirebaseCore (10.22.0)
  • FirebaseCoreExtension (10.22.0)
  • FirebaseCoreInternal (10.22.0)
  • FirebaseCrashlytics (10.22.0)
  • FirebaseInstallations (10.22.0)
  • FirebaseMessaging (10.22.0)
  • FirebasePerformance (10.22.0)
  • FirebaseRemoteConfig (10.22.0)
  • FirebaseSessions (10.22.0)
  • GoogleAppMeasurement (10.22.0)
  • GoogleDataTransport (9.4.1)
  • GoogleUtilities (7.13.0)

@schornon
Copy link

schornon commented May 24, 2024

I found a solution for myself.
...

In case you got an error like that:
Sandbox: cp(84447) deny(1) file-read-data /Users/username/workdir/ProjectName/ProjectName/Resources/Firebase/dev/GoogleService-info.plist
you can set Target's Build Settings ENABLE_USER_SCRIPT_SANDBOXING value to No
image

@Toolenaar
Copy link

I need this as well. But I guess this is never coming since it has been open since 2017

@lifely
Copy link

lifely commented Mar 7, 2025

#230 (comment)

I can believe the last time I've stumbled on this was 2018, 7 years later i find myself coming back here.

@iamdevmarcos
Copy link

i faced the same error 🥲

@ibrahim3zizz
Copy link

ibrahim3zizz commented Apr 15, 2025

Can I initiate Firebase with options without the file GoogleServices-Info.plist ?
Any updates ?

@narner
Copy link

narner commented May 2, 2025

Ditto; what's the latest status here? Working on an open-source app that I want to use Firebase Analytics with but would prefer to use Environment Variables and not the info plist

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests