ビルドスキームごとに異なるGoogleService-Info.plistを使用する


109

prodと1つのステージング(2つの異なるバンドル識別子を使用)のビルドスキームを使用しており、各スキ​​ームに個別のGoogleService-Info.plistを使用しようとしています。GCM(およびgooleログイン)を初期化するときに使用するplistファイルを手動で選択する方法はありますか?または、plistの使用を避けて手動で設定することは可能ですか?

ありがとう!


3
2つの異なるターゲットを使用しますか?次に、異なるコピーバンドルリソース(ビルドフェーズにある)に異なるファイル(同じ名前)を含めます。
Alexander Zimin

6
この記事は、medium.com / rocket-fuel /…に役立ちました。
Eugeny

私のために完全に機能しましたstackoverflow.com/a/58709334/11537677
Knight Fighter

回答:


142

細部

テスト済み:

  • Xcode 9.2
  • Xcode 10.2(10E125)
  • Xcode 11.0(11A420a)

解決

  1. プロジェクト内のすべてのGoogle.plistファイル(異なる名前)を含むフォルダーを作成します

ここに画像の説明を入力してください

  1. 実行スクリプトを追加

ここに画像の説明を入力してください

PATH_TO_GOOGLE_PLISTSの値を変更することを忘れないでください

コード

PATH_TO_GOOGLE_PLISTS="${PROJECT_DIR}/SM2/Application/Firebase"

case "${CONFIGURATION}" in

   "Debug_Staging" | "AdHoc_Staging" )
        cp -r "$PATH_TO_GOOGLE_PLISTS/GoogleService-Info-dev.plist" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/GoogleService-Info.plist" ;;

   "Debug_Poduction" | "AdHoc_Poduction" | "Distribution" | "Test_Poduction" )
        cp -r "$PATH_TO_GOOGLE_PLISTS/GoogleService-Info-prod.plist" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/GoogleService-Info.plist" ;;

    *)
        ;;
esac

スキーム名の作成

ここに画像の説明を入力してください


2
私の1日を
救ってください

1
これが正解です。どうやらFirebase Analyticsでは、を呼び出しconfigure(options:)た場合でも、アプリのルートディレクトリにそのplistファイルが必要です。github.com/firebase/quickstart-ios/issues/5
Rob Bajorek

2
これは非常に良い解決策であり、答えとして受け入れられるべきです。
ルークブランドンファレル

1
とても軽くて賢い、素晴らしい答え。ありがとうございました!
がぶちゃん

1
@smileBotあなたはスキップするかもしれません-r、詳細:Linux / Unixのcpコマンド
Vasily Bodnarchuk

73

@inidonaの答えがうまくいきました。Swiftに変換した後

Swift 2.3の場合:

let filePath = NSBundle.mainBundle().pathForResource("GoogleService-Info", ofType: "plist")
let options = FIROptions(contentsOfFile: filePath)
FIRApp.configureWithOptions(options)

Swift 3.0の場合:

let filePath = Bundle.main.path(forResource: "GoogleService-Info", ofType: "plist")!
let options = FIROptions(contentsOfFile: filePath)
FIRApp.configure(with: options)

Swift 4.0の場合:

let filePath = Bundle.main.path(forResource: "GoogleService-Info", ofType: "plist")!
let options = FirebaseOptions(contentsOfFile: filePath)
FirebaseApp.configure(options: options!)

1
上記のコードをGoogleService-Info.plist使用して、異なる場所に2つの異なるファイルがあるか、名前が異なる2つのファイルがあるか。実際のファイル名は何で、どこに配置されているかについて、もう少し情報を提供していただけませんか?
Varun Gupta

1
GoogleService-Info-dev.plistという名前の2つのファイルGoogleService-Info-live.plistがあります。このコードを使用すると、デフォルトのGoogleService-Info-dev.plistの条件ステートメントを使用する代わりに、使用するアプリの動作情報ファイルを通知できます。フラグを変更してファイルを
切り替える

うん、AppDelegateで
Essam Elmasry

1
'Could not Locate configuration file:' GoogleService-Info.plist '
orium

最近のドキュメントによると「警告:このアプローチは状況によってはアナリティクスの収集に影響を与える可能性があります」firebase.google.com/docs/projects/multiprojects
福山慎吾

30

この記事を確認してください:https : //medium.com/@brunolemos/how-to-setup-a-different-firebase-project-for-debug-and-release-environments-157b40512164

Xcodeのでは、プロジェクト内の2つのディレクトリを作成しますDebugRelease。各GoogleService-Info.plistファイルをそこに置きます。

AppDelegate.mdidFinishLaunchingWithOptionsメソッド内にコードを配置します。

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];

スウィフト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)

DebugReleaseフォルダの両方をドラッグアンドドロップしますBuild Phases > Copy Bundle Resources

ビルドフェーズ>バンドルリソースのコピー

それでおしまい :)


1
これでうまくいきました。これらのフォルダーを参照としてそこに追加する必要があります。追加しないと、実際にクラッシュします。ありがとう!
アイロニア2018

このソリューションはまだAnalyticsフレームワークの問題を解決していません.plist。どちらがロードされているかはわかりません。
生き生きとした

@Bruno Lemos、1つのxcodeプロジェクトから2つのFirebaseプロジェクトを同時に使用できますか?ないようDebugRelease?これを行おうとするとalready configured crash.、Firebaseの公式ドキュメントの最新の指示に従っていることが原因です。ありがとう
Tulon

24

この方法を使用してGoogleService-Info.plistを動的に構成し、異なるバンドル識別子に異なる名前を使用できると思います。

チャオ・アンドレアス

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"GoogleService-Info" ofType:@"plist"];
FIROptions *options = [[FIROptions alloc] initWithContentsOfFile:filePath];
[FIRApp configureWithOptions:options];

5
上記のコードで、2つの異なるファイルGoogleService-Info.plistファイルが異なる場所にありますか、または異なる名前の2つのファイルがある可能性があります。実際のファイル名は何で、どこに配置されているかについて、もう少し情報を提供していただけませんか?
Varun Gupta

4
私はconfigureWithOptions時にログにこのエラーを呼び出すのgettinています:Could not locate configuration file: 'GoogleService-Info.plist'
Babken Vardanyan

13

コードでGoogleがファイル名がGoogleServiceInfo.plistであると想定していることに気づきました。

 * The method |configureWithError:| will read from the file GoogleServices-Info.plist bundled with
 * your app target for the keys to configure each individual API. To generate your
 * GoogleServices-Info.plist, please go to https://developers.google.com/mobile/add
 *
 * @see GGLContext (Analytics)
 * @see GGLContext (SignIn)
 */
@interface GGLContext : NSObject

キーフレーズはこれです

アプリのターゲットにバンドルされているGoogleServices-Info.plistファイルから読み取る

そのため、同じファイルをコピーして別のディレクトリに配置し、別のターゲットにバインドしました。

ここに画像の説明を入力してください


おかげで、非常にシンプルで、Xcode 10.1、FirebaseCore(5.3.1)で非常にうまく機能します
infinity_coding7

アプリ内の複数のPlistまたは他のファイルが原因で発生する「複数のコマンドが生成する」エラーを回避する方法
Wahab Khan Jadon

11

GoogleService-Info.plist名前が異なる場合、分析結果に影響します。Firebaseはこれについて警告します。https://github.com/firebase/firebase-ios-sdk/issues/230#issuecomment-327138180。このため、これらのランタイムソリューションはどれも最高の分析結果を提供しません。

Analyticsを台無しにしない2つのソリューションがあります。

  1. 各スキームで異なるターゲットを使用し、の各バージョンをGoogleService-Info.plist独自のターゲットに関連付けます。Xcodeの右側にあるファイルインスペクタのターゲットメンバーシップを参照してください。詳細については、この質問を参照してください

  2. ビルドフェーズスクリプトを使用して、正しいバージョンGoogleService-Info.plistをビルドディレクトリにコピーします。ステージングとプロダクションに異なるバンドルIDを使用しています。これにより、アプリの両方のバージョンを並行してインストールできます。また、以下のスクリプトをGoogleService-Info.plist使用して、バンドルIDでさまざまなファイルに名前を付けることができます。例えば:

    • 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"

注:PATH_TO_CONFIGセットアップに合わせて変更する必要があります。

ビルドフェーズスクリプト


これはこれまでのところ最良の解決策です。Firebase CrashlyticsはGoogleService-Info.plistファイルのみを使用して、 'upload-symbols'スクリプトを使用したdSYMファイルをアップロードできるため、このソリューションは完全に機能します。
アレクセイガリシニコフ

6

Firebaseでplistを使用することは避けられません。これまでに見つけた最善の解決策は、両方のファイルを追加して名前を付けることです

GoogleService-Info_stage.plist

そして

GoogleService-Info_prod.plist

次に、コードから正しいファイルを呼び出すことができます。この方法では、ファイルがない場合でもアプリがクラッシュしません。FILENAMEをGoogleService-Info_prodまたはGoogleService-Info_stageに置き換えるだけです。

if let configFile = Bundle.main.path(forResource: "FILENAME", ofType: "plist"), 
    let options = FirebaseOptions(contentsOfFile: configFile)   
{
   FirebaseApp.configure(options: options)
}

ランタイム構成は、ドキュメントに記載されているように、分析レポートの問題を引き起こす可能性があります。
Alex

6

新しい開発者を助けるためにこの回答を投稿する必要があると思いますが、私の問題を解決する非常に良い記事を見つけ、それもあなたに役立つと約束します:) あなたの問題を解決するこの記事も
チェックしてください。

ステップ1: Firebase開発環境に対応するGoogleService-Info.plistをDevディレクトリに
コピーします。同様に、Firebase本番環境に対応するGoogleService-Info.plistをProdディレクトリにコピーします。[ 必要に応じてアイテムをコピーする]と[ターゲットに追加]の下のすべてのターゲットのチェックを必ず外してください。

(ステップ1画像リンク(評判が低いため画像を追加できません))

ステップ2:
Xcodeプロジェクトナビゲーターで、アプリターゲットを選択します。上部の[ビルドフェーズ]タブに切り替え、新しい実行スクリプトフェーズを追加します。フェーズに「Firebase環境のセットアップGoogleService-Info.plist」などの名前を付け、バンドルリソースのコピー」ステップの前に配置します。

ステップ3:ビルド構成に基づいて、
適切なGoogleService-Info.plistをApp Bundleにコピーするシェルスクリプトを実装します。次のシェルスクリプトをコピーして、作成したスクリプト実行フェーズに貼り付けます。

# Name of the resource we're selectively copying
GOOGLESERVICE_INFO_PLIST=GoogleService-Info.plist

# Get references to dev and prod versions of the GoogleService-Info.plist
# NOTE: These should only live on the file system and should NOT be part of the target (since we'll be adding them to the target manually)
GOOGLESERVICE_INFO_DEV=${PROJECT_DIR}/${TARGET_NAME}/Firebase/Dev/${GOOGLESERVICE_INFO_PLIST}
GOOGLESERVICE_INFO_PROD=${PROJECT_DIR}/${TARGET_NAME}/Firebase/Prod/${GOOGLESERVICE_INFO_PLIST}

# Make sure the dev version of GoogleService-Info.plist exists
echo "Looking for ${GOOGLESERVICE_INFO_PLIST} in ${GOOGLESERVICE_INFO_DEV}"
if [ ! -f $GOOGLESERVICE_INFO_DEV ]
then
    echo "No Development GoogleService-Info.plist found. Please ensure it's in the proper directory."
    exit 1
fi

# Make sure the prod version of GoogleService-Info.plist exists
echo "Looking for ${GOOGLESERVICE_INFO_PLIST} in ${GOOGLESERVICE_INFO_PROD}"
if [ ! -f $GOOGLESERVICE_INFO_PROD ]
then
    echo "No Production GoogleService-Info.plist found. Please ensure it's in the proper directory."
    exit 1
fi

# Get a reference to the destination location for the GoogleService-Info.plist
PLIST_DESTINATION=${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app
echo "Will copy ${GOOGLESERVICE_INFO_PLIST} to final destination: ${PLIST_DESTINATION}"

# Copy over the prod GoogleService-Info.plist for Release builds
if [ "${CONFIGURATION}" == "Release" ]
then
    echo "Using ${GOOGLESERVICE_INFO_PROD}"
    cp "${GOOGLESERVICE_INFO_PROD}" "${PLIST_DESTINATION}"
else
    echo "Using ${GOOGLESERVICE_INFO_DEV}"
    cp "${GOOGLESERVICE_INFO_DEV}" "${PLIST_DESTINATION}"
fi

3

この回答は@abboodの回答に非常に触発されていますが、その方法についてはもう少し具体的です。

各ターゲット、たとえばdev、stg、prodについて:

  • GoogleService-Info.plistターゲットにちなんで名付けられた別のフォルダに対応するものをダウンロードします
  • Xcodeで、アプリフォルダーを右クリックし、 Add files to "your app" ここに画像の説明を入力してください
  • ターゲットのを含むフォルダを選択し、とが選択されGoogleService-Info.plistていることを確認Copy items if neededCreate groupsて、ターゲットのリストで対応するターゲットのみをチェックして、を押しますAdd ここに画像の説明を入力してください

それでおしまい。これで、この構造に似たものができるはずです。

ここに画像の説明を入力してください

ターゲットをビルドすると、正しいものGoogleService-Info.plistが使用されます。


私には完璧に働きました。
Şafakゲゼル

2

Xamarin C#でこれを行う方法は次のとおりです。

string plistPath = NSBundle.MainBundle.PathForResource ("GoogleService-Info", "plist");
Options options = new Options (plistPath);
App.Configure (options);

Firebase名前空間を含めることを忘れないでください。

using Firebase.Analytics;

2

これが私の解決策です!

NSString *filePath;
if([self isProduction]){
    filePath = [[NSBundle mainBundle] pathForResource:@"GoogleService-Info" ofType:@"plist"];
}else{
    filePath = [[NSBundle mainBundle] pathForResource:@"GoogleService-Info-Sandbox" ofType:@"plist"];
}
FIROptions *options = [[FIROptions alloc] initWithContentsOfFile:filePath];
[FIRApp configureWithOptions:options];

以上です!


1

GoogleService-Info.plist.iOSアプリとGoogleサインインコンポーネントの統合を開始する前に、依存関係をダウンロードしてXcodeプロジェクトを構成する必要があるため、を使用しないと達成できないと思います。そして、このプロセスはそれGoogleService-Info.plistがそれに大きな要因を持っていることを示しています。

したがって、このSOの質問における解決策とアイデアは、問題の解決に役立ちます。GoogleService-Info plistアプリのメインコピーを2つの別々のフォルダーに移動し、各ターゲットでビルドフェーズの「ファイルのコピー」を使用して、ターゲット固有のplistをResourcesフォルダーにインポートしました。

また、このSOの質問を確認してください。問題の詳細情報やアイデアが得られる場合があります。


ここで、ターゲットは同じプロジェクトの異なるスキームを意味しますか?質問を読んだ後、ターゲットとは、同じターゲットの異なるビルドスキームだけでなく、完全に異なるビルドターゲットを意味することを収集しました。
Varun Gupta

1
しかし、スキームごとに構成が異なる1つのターゲットがある場合はどうでしょうか。
エヴィア2018年

1

Xcode 9.2では、両方のターゲットに「googleServiceInfo.plist」という名前のファイルが必要でしたが、「ビルドフェーズ」、「バンドルリソースのコピー」で指定された各ターゲットのディレクトリ/ファイルを別のディレクトリに配置しました。

上記は私の好ましい解決策ではありませんでしたが、以前は@inidonaの回答の行に沿って異なるファイル名を使用して、Swift 4に変換してみました。

 let filePath = Bundle.main.path(forResource: "googleServiceInfo-Pro", ofType: "plist")!
 let options = FirebaseOptions(contentsOfFile: filePath)
 FirebaseApp.configure(options: options!)

残念ながら、これではFirebaseのエラーメッセージは修正されませんでした。この質問では:Firebase iOS SDK-GoogleService-Info.plist以外の構成ファイルを使用すると、Firebaseポッドを更新することにより元の投稿者が修正したように見えるコンソール警告生成されますが、これは確認していません。


1

私はこれでこれを解決しました:

    #if STAGING
        if let filePath = Bundle.main.path(forResource: "GoogleService-Info-Dev", ofType: "plist"),
            let options = FirebaseOptions(contentsOfFile: filePath) {
                FirebaseApp.configure(options: options)
        } else {
            fatalError("GoogleService-Info-Dev.plist is missing!")
        }
    #else
        if let filePath = Bundle.main.path(forResource: "GoogleService-Info", ofType: "plist"),
            let options = FirebaseOptions(contentsOfFile: filePath) {
                FirebaseApp.configure(options: options)
        } else {
            fatalError("GoogleService-Info.plist is missing!")
        }
    #endif

1

あなたの一部がエラーに陥り、Xcodeが文句を言う場合

「複数のコマンドでGoogleService-Info.plistが生成されます」

@Knight Fighterの応答を適用した後、次の操作を実行できます。

  • ビルドフェーズを確認する>バンドルリソースをコピーする
  • 名前付きファイルをフィルター GoogleService-Info.plist
  • スクリプトを介して既にコピーされているため、参照を削除してください。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.