Ashutosh Billa

Firebase Configs in iOS: Using xcconfig to Select the Right GoogleService-Info.plist

May 16, 2026 · 4 min read

Cover image

If your iOS app has multiple build configurations — say, Debug and Release — you might also have different bundle IDs for each. And if you're using Firebase, that means different Firebase projects, which means different GoogleService-Info.plist files.

Here's a setup that keeps the right config tied to the right build configuration, automatically.


The core problem

Firebase's SDK discovers its configuration by looking for GoogleService-Info.plist inside the app bundle, by name. So whatever approach you use, you need to get the right file into the bundle under that exact filename at build time.


Step 1: Folder structure and xcconfig files

Create a Config/ directory with one subdirectory per configuration. Each subdirectory holds its own GoogleService-Info.plist and an .xcconfig file:

Folder structure with xcconfig files in Xcode project navigator

An .xcconfig file is a plain text file that defines build settings as key-value pairs. Xcode merges these into the build environment for whichever configuration the file is attached to — meaning any variable you define becomes available across your build phases, scripts, and targets, just like a built-in Xcode build setting.

Each xcconfig defines one variable pointing to its plist:

Debug.xcconfig

GOOGLE_SERVICE_INFO_PLIST = Config/Debug/GoogleService-Info.plist

Staging.xcconfig

GOOGLE_SERVICE_INFO_PLIST = Config/Staging/GoogleService-Info.plist

Release.xcconfig

GOOGLE_SERVICE_INFO_PLIST = Config/Release/GoogleService-Info.plist

The build script that runs later doesn't need to know which configuration is active. It just reads GOOGLE_SERVICE_INFO_PLIST — the xcconfig has already set it to the right value.

Do not add the plist files to the Copy Bundle Resources build phase. The build script handles copying — if you also add them to Copy Bundle Resources, you'll end up with duplicate resources and unpredictable behavior at runtime.


Step 2: Attach xcconfig files to build configurations

In Xcode, go to Project → Info → Configurations and assign:

  • Debug.xcconfig → Debug
  • Staging.xcconfig → Staging
  • Release.xcconfig → Release

Project → Info → Configurations in Xcode

When a configuration has an xcconfig attached, Xcode merges all the key-value pairs from that file into the build environment before the build starts. This is what makes GOOGLE_SERVICE_INFO_PLIST available to the run script in the next step — without the xcconfig attached, the variable simply doesn't exist and the script would fail.


Step 3: Add a Run Script build phase

Add a new Run Script phase and move it to run before Copy Bundle Resources:

PLIST_SOURCE="${PROJECT_DIR}/${TARGET_NAME}/${GOOGLE_SERVICE_INFO_PLIST}"
PLIST_DESTINATION="${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/GoogleService-Info.plist"
 
if [ ! -f "$PLIST_SOURCE" ]; then
    echo "error: GoogleService-Info.plist not found at ${PLIST_SOURCE}"
    exit 1
fi
 
cp "$PLIST_SOURCE" "$PLIST_DESTINATION"

No conditionals. No hardcoded paths. The GOOGLE_SERVICE_INFO_PLIST variable is already set by the xcconfig for the active build configuration — the script just uses it. If the source file is missing, the build fails with a red error pointing to the exact path it looked in.

Also declare the output file in the Output Files field of the run script phase to avoid a build warning and let Xcode skip the script on incremental builds when nothing has changed:

$(BUILT_PRODUCTS_DIR)/$(PRODUCT_NAME).app/GoogleService-Info.plist

Verifying the setup

To confirm the right values are being picked up, add these echo statements before the if condition in the above run script:

echo "Active configuration: ${CONFIGURATION}"
echo "Plist path: ${GOOGLE_SERVICE_INFO_PLIST}"
echo "Full source path: ${PLIST_SOURCE}"
echo "Destination: ${PLIST_DESTINATION}"

These print to the build log — open Report Navigator → latest build → expand the run script phase to see the output. If Debug and Release builds show different plist paths, the setup is working correctly.


The xcconfig files are the source of truth. Adding a new environment is one new file and one new configuration — nothing else changes.

My apps