I am using a build scheme for prod and one for staging (with 2 different bundle identifiers) and I am trying to use a separate GoogleService-Info.plist for each scheme. Is t
If some of you fall into an error and Xcode complains
"Multiple commands produce GoogleService-Info.plist"
after applying @Knight Fighter response, you may want to:
GoogleService-Info.plist
With Xcode 9.2, I have needed files for both targets to be named "googleServiceInfo.plist" but placed in different directories, with the directory/file for each target specified in "Build Phases", "Copy Bundle Resources".
The above was not my preferred solution, but I had previously tried using different filenames along the lines of @inidona's answer, converted to Swift 4:
let filePath = Bundle.main.path(forResource: "googleServiceInfo-Pro", ofType: "plist")!
let options = FirebaseOptions(contentsOfFile: filePath)
FirebaseApp.configure(options: options!)
Unfortunately, this did not correct the Firebase error messages. In this question: Firebase iOS SDK - Using configuration file other than GoogleService-Info.plist generates console warning the original poster seems to have fixed by updating the Firebase Pod but I have not confirmed this.
If the GoogleService-Info.plist
has a different name it will affect your analytics results. Firebase will warn you about this. https://github.com/firebase/firebase-ios-sdk/issues/230#issuecomment-327138180. For this reason, none of these runtime-solutions will provide the best analytics results.
There are two solutions that won't mess with Analytics.
Use a different target with each scheme and associate each version of GoogleService-Info.plist
with its own target. See Target Membership in the File inspector on the right hand side in Xcode. For further info See this question.
Use a build phase script to copy the correct version of GoogleService-Info.plist
into the build directory. I use a different bundle ID for staging and production. This enables me to have both versions of the app installed in parallel. It also means with the script below I can name my different GoogleService-Info.plist
files with the bundle ID. For example:
GoogleService-Info-com.example.app.plist
GoogleService-Info-com.example.app.staging.plist
PATH_TO_CONFIG=$SRCROOT/Config/GoogleService-Info-$PRODUCT_BUNDLE_IDENTIFIER.plist
FILENAME_IN_BUNDLE=GoogleService-Info.plist
BUILD_APP_DIR=${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app
echo cp $PATH_TO_CONFIG "$BUILD_APP_DIR/$FILENAME_IN_BUNDLE"
cp $PATH_TO_CONFIG "$BUILD_APP_DIR/$FILENAME_IN_BUNDLE"
Note: You will have to change PATH_TO_CONFIG
to suit you setup.
You cannot avoid to use the plist with Firebase. The best solution I found so far for you it would be to add both files and name it
GoogleService-Info_stage.plist
and
GoogleService-Info_prod.plist
Then from your code you can call the correct file. This way won't crash your app if you don't have the file. Just replace FILENAME with GoogleService-Info_prod or GoogleService-Info_stage.
if let configFile = Bundle.main.path(forResource: "FILENAME", ofType: "plist"),
let options = FirebaseOptions(contentsOfFile: configFile)
{
FirebaseApp.configure(options: options)
}
Check this article: https://medium.com/@brunolemos/how-to-setup-a-different-firebase-project-for-debug-and-release-environments-157b40512164
On Xcode, create two directories inside your project: Debug
and Release
. Put each GoogleService-Info.plist
file there.
On AppDelegate.m
, inside the didFinishLaunchingWithOptions
method, put the code:
Objective-C
NSString *filePath;
#ifdef DEBUG
NSLog(@"[FIREBASE] Development mode.");
filePath = [[NSBundle mainBundle] pathForResource:@"GoogleService-Info" ofType:@"plist" inDirectory:@"Debug"];
#else
NSLog(@"[FIREBASE] Production mode.");
filePath = [[NSBundle mainBundle] pathForResource:@"GoogleService-Info" ofType:@"plist" inDirectory:@"Release"];
#endif
FIROptions *options = [[FIROptions alloc] initWithContentsOfFile:filePath];
[FIRApp configureWithOptions:options];
Swift 4
var filePath:String!
#if DEBUG
print("[FIREBASE] Development mode.")
filePath = Bundle.main.path(forResource: "GoogleService-Info", ofType: "plist", inDirectory: "Debug")
#else
print("[FIREBASE] Production mode.")
filePath = Bundle.main.path(forResource: "GoogleService-Info", ofType: "plist", inDirectory: "Release")
#endif
let options = FirebaseOptions.init(contentsOfFile: filePath)!
FirebaseApp.configure(options: options)
Drag & drop both Debug
and Release
folders to the Build Phases > Copy Bundle Resources
:
That's it :)
@inidona 's answer worked for me. After I converted it to Swift
for Swift 2.3:
let filePath = NSBundle.mainBundle().pathForResource("GoogleService-Info", ofType: "plist")
let options = FIROptions(contentsOfFile: filePath)
FIRApp.configureWithOptions(options)
for Swift 3.0:
let filePath = Bundle.main.path(forResource: "GoogleService-Info", ofType: "plist")!
let options = FIROptions(contentsOfFile: filePath)
FIRApp.configure(with: options)
for Swift 4.0:
let filePath = Bundle.main.path(forResource: "GoogleService-Info", ofType: "plist")!
let options = FirebaseOptions(contentsOfFile: filePath)
FirebaseApp.configure(options: options!)