Fix 'GoogleService-Info.plist Not Found' and FirebaseApp.configure() Crash on iOS

Solve the classic Firebase startup crash caused by a missing or misconfigured GoogleService-Info.plist, from target membership to bundle ID mismatches, in order of likelihood.

Understanding the Crash

This problem almost always appears as an immediate crash at launch, right when FirebaseApp.configure() runs. The console message is usually explicit, something like Could not locate configuration file: 'GoogleService-Info.plist', or a fatal error stating the default Firebase app has not been configured. In some variations you instead see a later crash reading The default FirebaseApp instance must be configured before use, which is the same family of problem viewed from a different angle. What Firebase is telling you is simple: at runtime the SDK looked in your app bundle for the GoogleService-Info.plist that holds your project identifiers and API keys, and it either could not find the file or found one that does not match your app. Because configure() is called at launch, the crash is early and total, which is actually helpful because it fails loud and fast rather than silently misbehaving. The fixes are about making sure the correct config file is actually inside the built app bundle and that FirebaseApp.configure() runs at the right time, and they resolve in a predictable order from most to least common. Work through them in sequence and you will almost always land on the cause within the first two.

Fix 1: Confirm the File Is a Target Member

By far the most common cause is that GoogleService-Info.plist is visible in the Xcode project navigator but is not a member of the app target, so it never gets copied into the built bundle. Dragging a file into the navigator does not automatically add it to a target. Select GoogleService-Info.plist in the navigator, open the File Inspector on the right (the first tab), and look at the Target Membership section. Your app target must be checked. If it is not, check it, then clean the build folder and run again. You can further verify the file is being bundled by opening the target's Build Phases and expanding Copy Bundle Resources, where GoogleService-Info.plist should appear in the list; if it is missing there, add it. If your project has multiple targets that use Firebase, such as a widget or notification service extension, each of those targets needs the file as a member too. Getting target membership right fixes the overwhelming majority of these crashes, so check it first before considering any other cause. It costs only a few seconds and rules out the single most frequent mistake in Firebase setup.

Fix 2: Check for a Bundle ID Mismatch

If the file is present and bundled but the app still misbehaves or Firebase services fail, verify that the BUNDLE_ID inside GoogleService-Info.plist matches your app target's actual bundle identifier. Open the plist and find the BUNDLE_ID key, then compare it to the Bundle Identifier under your target's General tab in Xcode. They must be identical, including case. A mismatch happens when you registered the app in the Firebase console with one bundle ID but later changed the ID in Xcode, or when you downloaded the config file for a different app in the same Firebase project. If they differ, the cleanest fix is to go to the Firebase console, open your iOS app's settings, and either register the correct bundle ID or download the config file for the app whose bundle ID matches. Then replace the plist in your project with the correct one. Do not hand-edit the BUNDLE_ID in the plist to force a match, because the file also contains other identifiers tied to that specific registered app, and editing one value leaves the rest pointing at the wrong app. Watch out for build configurations that append a suffix such as .debug to the bundle identifier, since that silently breaks the match for that configuration.

Fix 3: Make Sure the File Is Actually in the Project

Sometimes the file was never added, or was added by reference to a location outside the project and later moved, leaving a dangling red entry in the navigator. Confirm the file physically exists in your project and is referenced correctly. If it shows red in the navigator, Xcode cannot find it on disk; delete the broken reference and re-add the file. When you drag it in, make sure Copy items if needed is checked so the file is copied into your project directory rather than merely linked to your Downloads folder, which breaks on other machines and in CI. If you cannot find the file at all, download a fresh copy from the Firebase console: open Project settings, scroll to Your apps, select the iOS app, and download GoogleService-Info.plist again. Re-add it with target membership checked. This fix handles the case where the crash is not about configuration timing but simply that no valid config file made it into the build. It is especially common on a freshly cloned repository where the plist was gitignored, so a teammate has the file locally but a new checkout does not, and the app crashes on first launch for everyone but the original author.

Fix 4: Call configure() Correctly and Once

The crash can also stem from how and when you call FirebaseApp.configure(). It must run exactly once, at launch, before any other Firebase API is used. In a SwiftUI app, the reliable pattern is an app delegate adaptor: create an AppDelegate conforming to UIApplicationDelegate, import FirebaseCore, and call FirebaseApp.configure() inside application(_:didFinishLaunchingWithOptions:), then wire it up with @UIApplicationDelegateAdaptor in your App struct. If you instead call configure() from a view's onAppear or after some asynchronous work, another Firebase call may run first and trigger the not-configured crash. Also ensure you are not calling a Firebase service in an initializer or global that executes before configure() does. If you support multiple environments with different plist files, use the FirebaseOptions initializer that loads a specific file by path and pass it to configure(options:), rather than relying on the default lookup. Confirm configure() is called on the main thread at startup. Correcting the placement and single invocation resolves the timing variants of this crash. A useful discipline is to keep configure() as the very first line of your didFinishLaunchingWithOptions and never call any Firebase API from a property initializer, since those can run before the app delegate even fires.

Fix 5: Multiple Environments and Renamed Files

A subtler cause appears when teams keep separate config files for development, staging, and production, such as GoogleService-Info-Dev.plist and GoogleService-Info-Prod.plist. The default FirebaseApp.configure() looks specifically for a file named exactly GoogleService-Info.plist, so a renamed file will not be found by the default lookup and you get the not-found crash. You have two clean options. One is to use a build phase run script that copies the correct environment file to GoogleService-Info.plist in the bundle based on the build configuration, so the default lookup succeeds. The other is to load the file explicitly in code: build a FirebaseOptions instance with contentsOfFile pointing at the correct plist path from your bundle, then call FirebaseApp.configure(options:). Both approaches let you ship distinct Firebase projects per environment without renaming at the wrong moment. Whichever you choose, make sure each environment's file is a member of the target and that exactly one valid configuration reaches configure() at runtime, so you avoid pointing production builds at a development backend. Document whichever approach you pick in the repository, because environment-selection logic is exactly the kind of setup a new team member will not know to look for when their build crashes.

Verifying the Fix and Preventing Recurrence

After applying a fix, clean the build folder with Product, Clean Build Folder and delete derived data if the old state seems cached, then run the app. A successful launch with no configuration crash and Firebase startup logs in the console confirms the file is now found and configure() ran. For extra certainty, add a harmless Firebase call after configuration, such as reading FirebaseApp.app() and confirming it is non-nil. To prevent this class of crash from returning, commit GoogleService-Info.plist to your repository (or manage it through your environment-copy script) so teammates and CI always have it, keep the bundle ID identical across Xcode and the Firebase console, and standardize on the app delegate pattern for a single, well-placed configure() call. If you use multiple environments, document the copy-script or FirebaseOptions approach so no one accidentally ships the wrong backend. These habits turn a frequently recurring startup crash into a one-time setup step you never have to revisit. Because the config file carries no server secret, committing it is generally safe and is the simplest way to guarantee every checkout and CI run builds with a valid configuration in place.

Frequently Asked Questions

Why does my app crash the moment it launches after adding Firebase?

FirebaseApp.configure() ran but could not find a valid GoogleService-Info.plist in the app bundle. The usual reason is that the file is in the project navigator but not a member of the app target, so it never gets copied into the build. Check Target Membership in the File Inspector and enable your app target.

How do I confirm the plist is actually in my app bundle?

Open your target's Build Phases and expand Copy Bundle Resources. GoogleService-Info.plist should be listed there. If it is missing, the file is not being bundled even if it appears in the navigator. Add it to Copy Bundle Resources or fix its target membership, then clean and rebuild.

Does the bundle ID in the plist have to match my app?

Yes. The BUNDLE_ID inside GoogleService-Info.plist must exactly match your target's Bundle Identifier in Xcode. A mismatch happens when the app's ID changed after registration or you downloaded the wrong app's config. Fix it by registering the correct bundle ID in the Firebase console and downloading the matching file, not by editing the plist by hand.

Where should FirebaseApp.configure() be called in SwiftUI?

Call it once at launch, before any other Firebase API, from an app delegate adaptor's didFinishLaunchingWithOptions. Wire the AppDelegate to your App struct with @UIApplicationDelegateAdaptor. Calling configure() late, such as in a view's onAppear, risks another Firebase call running first and crashing with the not-configured error.

I renamed the file for different environments and now it crashes. Why?

The default configure() looks for a file named exactly GoogleService-Info.plist. A renamed file like GoogleService-Info-Prod.plist is not found by the default lookup. Either use a build phase script to copy the right file to that exact name, or load it explicitly with FirebaseOptions(contentsOfFile:) and call configure(options:).

Is GoogleService-Info.plist safe to commit to git?

Generally yes. It contains project identifiers and client API keys that are designed to ship inside your app, not private server secrets. Committing it ensures teammates and CI always build with the config file. Protect your backend with Security Rules and App Check rather than relying on hiding this file.