Verwenden Sie unterschiedliche GoogleService-Info.plist für unterschiedliche Build-Schemata


109

Ich verwende ein Build-Schema für Prod und eines für Staging (mit 2 verschiedenen Bundle-IDs) und versuche, für jedes Schema eine separate GoogleService-Info.plist zu verwenden. Gibt es eine Möglichkeit, die Plist-Datei, die beim Initialisieren von GCM (und beim Goole-Login) verwendet werden soll, manuell auszuwählen? Oder ist es möglich, die Verwendung der Plist zu vermeiden und das Setup manuell durchzuführen?

Vielen Dank!


3
Sie verwenden zwei verschiedene Ziele? Verfügen Sie dann über verschiedene Dateien (mit demselben Namen) in verschiedenen Copy Bundle-Ressourcen (in Erstellungsphasen).
Alexander Zimin

6
Dieser Artikel war hilfreich für mich medium.com/rocket-fuel/… .
Eugeny

Funktionierte perfekt für mich stackoverflow.com/a/58709334/11537677
Knight Fighter

Antworten:


141

Einzelheiten

Getestet am:

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

Lösung

  1. Erstellen Sie einen Ordner mit all Ihren Google.plist-Dateien (mit unterschiedlichen Namen) im Projekt

Geben Sie hier die Bildbeschreibung ein

  1. Run-Skript hinzufügen

Geben Sie hier die Bildbeschreibung ein

Vergessen Sie nicht, den Wert PATH_TO_GOOGLE_PLISTS zu ändern

Code

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

Erstellen Sie Schemanamen

Geben Sie hier die Bildbeschreibung ein


2
Speichern Sie meinen Tag große Antwort
Siddh

1
Das ist die richtige Antwort. Anscheinend benötigt Firebase Analytics diese plist-Datei im Stammverzeichnis Ihrer App, selbst wenn Sie anrufen configure(options:). github.com/firebase/quickstart-ios/issues/5
Rob Bajorek

2
Dies ist eine sehr schöne Lösung und sollte als Antwort akzeptiert werden.
Luke Brandon Farrell

1
Sehr leicht und klug, tolle Antwort. Danke dir!
Gabuchan

1
@smileBot können Sie überspringen -r, weitere Informationen: Befehl cp in Linux / Unix
Vasily Bodnarchuk

73

@inidonas Antwort hat bei mir funktioniert. Nachdem ich es auf Swift umgestellt habe

für Swift 2.3:

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

für Swift 3.0:

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

für Swift 4.0:

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

1
Haben Sie mit dem obigen Code zwei verschiedene Dateidateien GoogleService-Info.plistan verschiedenen Speicherorten oder möglicherweise zwei Dateien mit unterschiedlichen Namen. Könnten Sie bitte weitere Informationen darüber geben, wie die tatsächlichen Dateinamen lauten und wo sie platziert sind?
Varun Gupta

1
Ich habe 2 Dateien mit dem Namen GoogleService-Info-dev.plist GoogleService-Info-live.plist Mit diesem Code können Sie Ihrer App mitteilen, mit welcher Info-Datei Sie arbeiten möchten, anstatt der standardmäßigen bedingten Anweisung GoogleService-Info-dev.plist oder Zielflags zum Wechseln zwischen Ihren Dateien
Essam Elmasry

Ja, in der AppDelegate
Essam Elmasry

1
gibt mir 'Konfigurationsdatei konnte nicht gefunden werden:' GoogleService-Info.plist ''
Orium

In einem kürzlich veröffentlichten Dokument heißt es: "Warnung: Dieser Ansatz kann sich unter bestimmten Umständen auf die Analytics-Erfassung auswirken." Firebase.google.com/docs/projects/multiprojects
Shingo Fukuyama

30

Überprüfen Sie diesen Artikel: https://medium.com/@brunolemos/how-to-setup-a-different-firebase-project-for-debug-and-release-environments-157b40512164

Erstellen Sie unter Xcode zwei Verzeichnisse in Ihrem Projekt: Debugund Release. Legen Sie jede GoogleService-Info.plistDatei dort ab.

Setzen Sie AppDelegate.minnerhalb der didFinishLaunchingWithOptionsMethode den Code ein:

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

Ziehen Sie beide Debugund ReleaseOrdner per Drag & Drop auf Build Phases > Copy Bundle Resources:

Phasen erstellen> Bundle-Ressourcen kopieren

Das ist es :)


1
Das hat bei mir funktioniert. Sie müssen diese Ordner dort als Referenz hinzufügen, sonst stürzt sie tatsächlich ab. Vielen Dank!
Eironeia

Diese Lösung löst das Problem für das AnalyticsFramework immer noch nicht. Sie können nicht erkennen, welches .plistgeladen wird.
Lebenslanger

@Bruno Lemos, Kann ich zwei Firebase-Projekte aus einem Xcode-Projekt gleichzeitig verwenden? Nicht als Debug& Release? Denn wenn ich dies versuche, habe ich immer already configured crash.die neuesten Anweisungen aus dem offiziellen Firebase-Dokument befolgt. Vielen Dank
Tulon

24

Ich denke, Sie können auf diese Weise Ihre GoogleService-Info.plist dynamisch konfigurieren und unterschiedliche Namen für unterschiedliche Bundle-IDs verwenden.

ciao Andreas

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

5
Haben Sie mit dem obigen Code zwei verschiedene Dateien GoogleService-Info.plist-Dateien an verschiedenen Speicherorten oder möglicherweise zwei Dateien mit unterschiedlichen Namen. Könnten Sie bitte weitere Informationen darüber geben, wie die tatsächlichen Dateinamen lauten und wo sie platziert sind?
Varun Gupta

4
Ich erhalte diesen Fehler im Protokoll während des Aufrufs von configureWithOptions:Could not locate configuration file: 'GoogleService-Info.plist'
Babken Vardanyan

13

Ich habe festgestellt, dass Google erwartet, dass der Dateiname im Code GoogleServiceInfo.plist lautet:

 * 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

Der Schlüsselbegriff ist dieser

Lesen Sie aus der Datei GoogleServices-Info.plist, die mit Ihrem App-Ziel gebündelt ist

Also habe ich einfach dieselbe Datei kopiert und in verschiedene Verzeichnisse gestellt und an verschiedene Ziele gebunden:

Geben Sie hier die Bildbeschreibung ein


Danke, sehr einfach und funktioniert sehr gut für mich, Xcode 10.1, FirebaseCore (5.3.1)
infinity_coding7

So vermeiden Sie den Fehler "Mehrere Befehle erzeugen", der aufgrund mehrerer Plist- oder anderer Dateien in App
Wahab Khan Jadon

11

Wenn das GoogleService-Info.plisteinen anderen Namen hat, wirkt sich dies auf Ihre Analyseergebnisse aus. Firebase warnt Sie davor. https://github.com/firebase/firebase-ios-sdk/issues/230#issuecomment-327138180 . Aus diesem Grund liefert keine dieser Laufzeitlösungen die besten Analyseergebnisse.

Es gibt zwei Lösungen, die sich nicht mit Analytics herumschlagen.

  1. Verwenden Sie für jedes Schema ein anderes Ziel und ordnen Sie jede Version GoogleService-Info.plisteinem eigenen Ziel zu. Siehe Zielmitgliedschaft im Dateiinspektor auf der rechten Seite in Xcode. Weitere Informationen Siehe diese Frage .

  2. Verwenden Sie ein Build-Phase-Skript, um die richtige Version von GoogleService-Info.plistin das Build-Verzeichnis zu kopieren . Ich verwende eine andere Bundle-ID für die Bereitstellung und Produktion. Dadurch kann ich beide Versionen der App parallel installieren. Dies bedeutet auch, dass ich mit dem folgenden Skript meine verschiedenen GoogleService-Info.plistDateien mit der Bundle-ID benennen kann . Beispielsweise:

    • GoogleService-Info-com.example.app.plist
    • GoogleService-Info-com.example.app.staging.plist

Phase-Skript erstellen

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"

Hinweis: Sie müssen sich PATH_TO_CONFIGentsprechend Ihrer Einrichtung ändern .

Phase-Skript erstellen


Dies ist die bisher beste Lösung. Da Firebase Crashlytics nur die Datei GoogleService-Info.plist verwenden kann, um dSYM-Dateien mithilfe des Skripts "Upload-Symbole" hochzuladen, funktioniert diese Lösung einwandfrei!
Alexey Galishnikov

6

Sie können es nicht vermeiden, die Liste mit Firebase zu verwenden. Die beste Lösung, die ich bisher für Sie gefunden habe, wäre, beide Dateien hinzuzufügen und zu benennen

GoogleService-Info_stage.plist

und

GoogleService-Info_prod.plist

Dann können Sie aus Ihrem Code die richtige Datei aufrufen. Auf diese Weise stürzt Ihre App nicht ab, wenn Sie die Datei nicht haben. Ersetzen Sie einfach FILENAME durch GoogleService-Info_prod oder GoogleService-Info_stage.

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

Laufzeitkonfigurationen können zu Problemen bei der Analyseberichterstattung führen, wie in den Dokumenten erwähnt .
Alex

6

Spät, aber ich denke, ich muss diese Antwort posten, um neuen Entwicklern zu helfen. Ich habe einen sehr guten Artikel gefunden, der mein Problem behebt, und ich verspreche, dass er Ihnen auch helfen kann :)
Überprüfen Sie diesen Artikel, der auch Ihr Problem löst .

Schritt 1:
Kopieren Sie die Ihrer Firebase-Entwicklungsumgebung entsprechende GoogleService-Info.plist in das Dev- Verzeichnis. Kopieren Sie in ähnlicher Weise die GoogleService-Info.plist , die Ihrer Firebase-Produktionsumgebung entspricht, in das Prod- Verzeichnis. Deaktivieren Sie unter "Zu Zielen hinzufügen " die Option "Elemente bei Bedarf kopieren" und alle Ziele .

(Schritt 1 Bildlink (Ich kann kein Bild hinzufügen, weil ich weniger Reputation habe))

Schritt 2:
Wählen Sie im Xcode-Projektnavigator das App-Ziel aus. Wechseln Sie oben zur Registerkarte "Erstellungsphasen" und fügen Sie eine neue Ausführungsskriptphase hinzu . Nennen Sie die Phase "Firebase-Umgebung einrichten GoogleService-Info.plist" oder etwas in diesem Sinne und platzieren Sie sie vor dem Schritt "Bundle-Ressourcen kopieren" .

Schritt 3:
Implementieren Sie ein Shell-Skript, das die entsprechende GoogleService-Info.plist basierend auf der Build-Konfiguration in das App-Bundle kopiert . Kopieren Sie das folgende Shell-Skript und fügen Sie es in die gerade erstellte Ausführungsskriptphase ein:

# 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

Diese Antwort ist sehr stark von @abboods Antwort inspiriert , aber etwas genauer, wie es geht.

Für jedes Ihrer Ziele, z. B. dev, stg, prod:

  • Laden Sie den entsprechenden GoogleService-Info.plistOrdner herunter, der nach Ihrem Ziel benannt ist
  • Klicken Sie in Xcode mit der rechten Maustaste auf Ihren App-Ordner und wählen Sie Add files to "your app" Geben Sie hier die Bildbeschreibung ein
  • Wählen Sie den Ordner des Ziels enthalten GoogleService-Info.plist, stellen Sie sicher , Copy items if neededund Create groupsausgewählt werden , überprüfen nur das entsprechende Ziel in der Liste der Ziele, und drücken SieAdd Geben Sie hier die Bildbeschreibung ein

Das ist es. Jetzt sollten Sie etwas Ähnliches wie diese Struktur haben

Geben Sie hier die Bildbeschreibung ein

Wenn Sie ein Ziel erstellen, wird das richtige GoogleService-Info.plistverwendet.


Hat perfekt für mich funktioniert.
Şafak Gezer

2

So geht's in Xamarin C #:

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

Denken Sie daran, den Firebase-Namespace einzuschließen:

using Firebase.Analytics;

2

Das ist meine Lösung!

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

Und das ist es!


1

Ich denke, es ist nicht möglich, dies ohne die Verwendung von zu erreichen. GoogleService-Info.plist.Bevor Sie mit der Integration Ihrer iOS-App in die Google Sign-In-Komponenten beginnen können, müssen Sie die Abhängigkeiten herunterladen und Ihr Xcode-Projekt konfigurieren. Und dieser Prozess zeigt, dass dies GoogleService-Info.plisteinen großen Einfluss hat.

Also die Lösungen und Ideen hier in diesem SO-Frage können Ihnen also bei Ihrem Problem helfen. Verschieben Sie einfach die Hauptkopie GoogleService-Info plistder App aus der App in zwei separate Ordner und importieren Sie dann die Zielphasen "Dateien kopieren" auf jedem Ziel, um die zielspezifische Liste in den Ordner "Ressourcen" zu importieren.

Überprüfen Sie auch diese SO-Frage , sie könnte Ihnen weitere Informationen / Ideen zu Ihrem Problem geben.


Bedeutet Ziel hier ein anderes Schema für dasselbe Projekt? Nachdem ich die Fragen gelesen hatte, stellte ich fest, dass das Ziel insgesamt ein anderes Build-Ziel bedeutet und nicht nur ein anderes Build-Schema für dasselbe Ziel.
Varun Gupta

1
Was aber, wenn Sie für jedes Schema ein Ziel mit einer anderen Konfiguration haben?
Evya

1

Mit Xcode 9.2 benötigte ich Dateien für beide Ziele mit dem Namen "googleServiceInfo.plist", die jedoch in verschiedenen Verzeichnissen abgelegt wurden. Das Verzeichnis / die Datei für jedes Ziel wurde unter "Phasen erstellen", "Bundle-Ressourcen kopieren" angegeben.

Das Obige war nicht meine bevorzugte Lösung, aber ich hatte zuvor versucht, verschiedene Dateinamen gemäß der Antwort von @ inidona zu verwenden, die in Swift 4 konvertiert wurde:

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

Leider wurden die Firebase-Fehlermeldungen dadurch nicht korrigiert. In dieser Frage: Firebase iOS SDK - Wenn Sie eine andere Konfigurationsdatei als GoogleService-Info.plist verwenden, wird eine Konsolenwarnung generiert, die das Originalposter durch Aktualisierung des Firebase -Pods behoben zu haben scheint. Ich habe dies jedoch nicht bestätigt.


1

Ich habe das dadurch gelöst:

    #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

Wenn einige von Ihnen in einen Fehler geraten und Xcode sich beschwert

"Mehrere Befehle erzeugen GoogleService-Info.plist"

Nachdem Sie die Antwort von @Knight Fighter angewendet haben , möchten Sie möglicherweise:

  • Aktivieren Sie Build-Phasen> Bundle-Ressourcen kopieren
  • Filter nach benannten Dateien GoogleService-Info.plist
  • Entfernen Sie alle Verweise, die Sie darauf haben, da es bereits durch das Skript kopiert wird.
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.