Gunakan GoogleService-Info.plist yang berbeda untuk skema build yang berbeda

110

Saya menggunakan skema build untuk prod dan satu untuk pementasan (dengan 2 pengenal paket berbeda) dan saya mencoba menggunakan GoogleService-Info.plist terpisah untuk setiap skema. Apakah ada cara untuk memilih file plist secara manual untuk digunakan saat menginisialisasi GCM (dan login goole)? Atau mungkinkah menghindari penggunaan plist dan melakukan penyetelan secara manual?

Terima kasih!

nwaxgui
sumber
3
Anda menggunakan dua target berbeda? Kemudian memiliki file yang berbeda (dengan nama yang sama) dalam Sumber Daya Bundel Salin yang berbeda (yang dalam fase pembuatan).
Alexander Zimin
6
Artikel itu sangat membantu saya medium.com/rocket-fuel/… .
Eugeny
Bekerja dengan sempurna untuk saya stackoverflow.com/a/58709334/11537677
Knight Fighter

Jawaban:

142

Detail

Diuji pada:

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

Larutan

  1. Buat folder dengan semua file Google.plist Anda (dengan nama berbeda) dalam proyek

masukkan deskripsi gambar di sini

  1. Tambahkan skrip run

masukkan deskripsi gambar di sini

Jangan lupa untuk mengubah nilai PATH_TO_GOOGLE_PLISTS

Kode

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

Buat nama skema

masukkan deskripsi gambar di sini

Bodnarchuk dengan mudah
sumber
2
Selamatkan hari saya jawaban yang bagus
Siddh
1
Ini adalah jawaban yang benar. Rupanya Firebase Analytics membutuhkan file plist tersebut di direktori root aplikasi Anda, meskipun Anda memanggilnya configure(options:). github.com/firebase/quickstart-ios/issues/5
Rob Bajorek
2
Ini adalah solusi yang sangat bagus dan harus diterima sebagai jawabannya.
Luke Brandon Farrell
1
Sangat ringan & cerdas, jawaban yang bagus. Terima kasih!
gabuchan
1
@smileBot Anda dapat melewati -r, info lebih lanjut: perintah cp di Linux / Unix
Vasily Bodnarchuk
73

Jawaban @inidona berhasil untuk saya. Setelah saya mengubahnya menjadi Swift

untuk Swift 2.3:

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

untuk Swift 3.0:

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

untuk Swift 4.0:

let filePath = Bundle.main.path(forResource: "GoogleService-Info", ofType: "plist")!
let options = FirebaseOptions(contentsOfFile: filePath)
FirebaseApp.configure(options: options!)
Essam Elmasry
sumber
1
Dengan kode di atas, apakah Anda memiliki dua GoogleService-Info.plistfile berbeda di lokasi berbeda atau mungkin dua file dengan nama berbeda. Bisakah Anda memberikan beberapa informasi lebih lanjut tentang apa nama file yang sebenarnya dan di mana mereka ditempatkan?
Varun Gupta
1
Saya memiliki 2 file bernama GoogleService-Info-dev.plist GoogleService-Info-live.plist kode ini memungkinkan Anda memberi tahu aplikasi Anda file info yang ingin Anda gunakan alih-alih menggunakan GoogleService-Info-dev.plist default gunakan pernyataan bersyarat atau bendera target untuk bergantian di antara file Anda
Essam Elmasry
yup, di AppDelegate
Essam Elmasry
1
memberi saya 'Tidak dapat menemukan file konfigurasi:' GoogleService-Info.plist ''
orium
Dokumen terbaru mengatakan "Peringatan: Pendekatan ini dapat memengaruhi pengumpulan Analytics dalam beberapa keadaan" firebase.google.com/docs/projects/multiprojects
Shingo Fukuyama
30

Periksa artikel ini: https://medium.com/@brunolemos/how-to-setup-a-different-firebase-project-for-debug-and-release-environments-157b40512164

Di Xcode, buat dua direktori di dalam proyek Anda: Debugdan Release. Taruh setiap GoogleService-Info.plistfile di sana.

Di AppDelegate.m, di dalam didFinishLaunchingWithOptionsmetode, masukkan kode:

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

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

Seret & lepas keduanya Debugdan Releasefolder ke Build Phases > Copy Bundle Resources:

Bangun Fase> Salin Sumber Daya Bundel

Itu dia :)

Bruno Lemos
sumber
1
Ini berhasil untuk saya. Anda harus menambahkan folder ini di sana sebagai referensi, jika tidak maka akan macet. Terima kasih!
Eironeia
Solusi ini masih belum menyelesaikan masalah untuk Analyticskerangka kerja, Anda tidak dapat membedakan mana .plistyang sedang dimuat.
Seumur hidup
@Bruno Lemos, Dapatkah saya menggunakan dua proyek Firebase dari satu proyek xcode secara bersamaan? Bukan sebagai Debug& Release? Karena ketika saya mencoba melakukan ini saya selalu berakhir dengan already configured crash.saya telah mengikuti instruksi terbaru dari dokumen resmi Firebase. Terima kasih
Tulon
24

Saya rasa Anda dapat menggunakan cara ini untuk mengonfigurasi GoogleService-Info.plist Anda secara dinamis dan menggunakan nama yang berbeda untuk pengenal paket yang berbeda.

ciao Andreas

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"GoogleService-Info" ofType:@"plist"];
FIROptions *options = [[FIROptions alloc] initWithContentsOfFile:filePath];
[FIRApp configureWithOptions:options];
inidona
sumber
5
Dengan kode diatas, apakah anda memiliki dua file berbeda yaitu file GoogleService-Info.plist di lokasi yang berbeda atau mungkin dua file dengan nama yang berbeda. Bisakah Anda memberikan beberapa informasi lebih lanjut tentang apa nama file yang sebenarnya dan di mana mereka ditempatkan?
Varun Gupta
4
Saya mendapatkan kesalahan ini di log selama panggilan configureWithOptions:Could not locate configuration file: 'GoogleService-Info.plist'
Babken Vardanyan
14

Saya perhatikan bahwa google mengharapkan nama file menjadi GoogleServiceInfo.plist dalam kode:

 * 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

frase kuncinya adalah yang ini

membaca dari file GoogleServices-Info.plist yang dipaketkan dengan target aplikasi Anda

Jadi saya cukup menyalin file yang sama dan memasukkannya ke dalam direktori yang berbeda, dan membatasinya ke target yang berbeda:

masukkan deskripsi gambar di sini

biara
sumber
Terima kasih, sangat sederhana dan berfungsi sangat baik untuk saya, Xcode 10.1, FirebaseCore (5.3.1)
infinity_coding7
Bagaimana menghindari kesalahan "Multiple command menghasilkan" yang terjadi setelah karena beberapa Plist atau file lain dalam App
Wahab Khan Jadon
11

Jika GoogleService-Info.plistmemiliki nama berbeda, itu akan memengaruhi hasil analitik Anda. Firebase akan memperingatkan Anda tentang ini. https://github.com/firebase/firebase-ios-sdk/issues/230#issuecomment-327138180 . Karena alasan ini, tidak ada solusi runtime ini yang akan memberikan hasil analitik terbaik.

Ada dua solusi yang tidak akan mengacaukan Analytics.

  1. Gunakan target yang berbeda dengan setiap skema dan kaitkan setiap versi GoogleService-Info.plistdengan targetnya sendiri. Lihat Target Membership di File inspector di sisi kanan Xcode. Untuk info lebih lanjut Lihat pertanyaan ini .

  2. Menggunakan script membangun fase untuk menyalin versi yang benar dari GoogleService-Info.plistke direktori build. Saya menggunakan ID bundel yang berbeda untuk pementasan dan produksi. Ini memungkinkan saya memasang kedua versi aplikasi secara paralel. Ini juga berarti dengan skrip di bawah ini saya dapat memberi nama GoogleService-Info.plistfile saya yang berbeda dengan ID bundel. Sebagai contoh:

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

Buat Phase Script

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"

Catatan: Anda harus berganti PATH_TO_CONFIGpakaian sesuai pengaturan Anda.

Buat Phase Script

Onato
sumber
Ini adalah solusi terbaik sejauh ini. Karena Firebase Crashlytics hanya dapat menggunakan file GoogleService-Info.plist untuk mengupload file dSYM menggunakan skrip 'upload-symbol' - solusi ini bekerja dengan sempurna!
Alexey Galishnikov
6

Anda tidak dapat menghindari penggunaan plist dengan Firebase. Solusi terbaik yang saya temukan sejauh ini untuk Anda adalah dengan menambahkan kedua file dan menamainya

GoogleService-Info_stage.plist

dan

GoogleService-Info_prod.plist

Kemudian dari kode Anda, Anda dapat memanggil file yang benar. Dengan cara ini tidak akan merusak aplikasi Anda jika Anda tidak memiliki file tersebut. Cukup ganti FILENAME dengan GoogleService-Info_prod atau GoogleService-Info_stage.

if let configFile = Bundle.main.path(forResource: "FILENAME", ofType: "plist"), 
    let options = FirebaseOptions(contentsOfFile: configFile)   
{
   FirebaseApp.configure(options: options)
}
pierre23
sumber
Konfigurasi waktu proses dapat menyebabkan masalah pelaporan analitik seperti yang disebutkan dalam dokumen .
Alex
6

Terlambat tetapi saya pikir saya harus memposting jawaban ini untuk membantu pengembang baru, saya menemukan artikel yang sangat bagus yang menjawab masalah saya dan saya berjanji itu dapat membantu Anda juga :)
Periksa artikel ini yang menyelesaikan masalah Anda juga.

Langkah 1:
Salin GoogleService-Info.plist yang sesuai dengan lingkungan pengembangan Firebase Anda ke dalam direktori Dev . Demikian pula, salin GoogleService-Info.plist yang sesuai dengan lingkungan produksi Firebase Anda di direktori Prod . Pastikan untuk menghapus centang "Salin item jika perlu" dan semua target di bawah "Tambahkan ke target" .

(Langkah 1 tautan gambar (Saya tidak dapat menambahkan gambar karena reputasi kurang))

Langkah 2:
Di navigator proyek Xcode, pilih target aplikasi. Beralih ke tab Build Phases di bagian atas, lalu tambahkan New Run Script Phase . Beri nama fase "Setup Firebase Environment GoogleService-Info.plist" , atau sesuatu dari efek tersebut, dan letakkan sebelum langkah "Copy Bundle Resources" .

Langkah 3:
Terapkan skrip shell yang akan menyalin GoogleService-Info.plist yang sesuai ke dalam app bundle berdasarkan konfigurasi build. Salin dan tempel skrip shell berikut ke dalam fase skrip jalankan yang baru saja Anda buat:

# 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
Knight Fighter
sumber
3

Jawaban ini sangat terinspirasi oleh jawaban @abbood , tetapi sedikit lebih spesifik tentang cara melakukannya.

Untuk setiap target Anda, misalnya dev, stg, prod:

  • Unduh yang sesuai GoogleService-Info.plistke folder terpisah yang dinamai sesuai target Anda
  • Di Xcode, klik kanan folder aplikasi Anda dan pilih Add files to "your app" masukkan deskripsi gambar di sini
  • Pilih folder yang berisi target GoogleService-Info.plist, pastikan Copy items if neededdan Create groupsdipilih, centang hanya target yang sesuai di daftar target, dan tekanAdd masukkan deskripsi gambar di sini

Itu dia. Sekarang Anda harus memiliki sesuatu yang mirip dengan struktur ini

masukkan deskripsi gambar di sini

Saat Anda membangun target, yang benar GoogleService-Info.plistakan digunakan.

Bjørn Egil
sumber
Bekerja dengan sempurna untuk saya.
Şafak Gezer
2

Berikut cara melakukannya di Xamarin C #:

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

Ingatlah untuk menyertakan namespace Firebase:

using Firebase.Analytics;
Sune Kjærgård
sumber
2

Ini solusi saya!

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

Dan itu dia!

Ignacio Hernández
sumber
1

Saya pikir itu tidak mungkin dicapai tanpa menggunakan GoogleService-Info.plist.Karena sebelum Anda dapat mulai mengintegrasikan aplikasi iOS Anda dengan komponen Masuk Google, Anda harus mengunduh dependensi dan mengonfigurasi proyek Xcode Anda. Dan proses ini menunjukkan bahwa GoogleService-Info.plistada faktor besar di dalamnya.

Jadi solusi dan ide dalam pertanyaan SO ini dapat membantu Anda dengan masalah Anda. Baru saja memindahkan salinan utama dari GoogleService-Info plistaplikasi ke dalam 2 folder terpisah, lalu gunakan "Salin File" Fase Build pada setiap target untuk mengimpor plist spesifik target ke dalam folder Resources.

Juga periksa pertanyaan SO ini , ini mungkin memberi Anda lebih banyak informasi / ide untuk masalah Anda.

KENdi
sumber
Di sini, apakah target berarti skema yang berbeda untuk proyek yang sama? Setelah membaca pertanyaan, saya menyimpulkan bahwa target berarti target build yang berbeda sama sekali dan bukan hanya skema build yang berbeda untuk target yang sama.
Varun Gupta
1
Tetapi bagaimana jika Anda memiliki satu target dengan konfigurasi berbeda untuk setiap skema?
evya
1

Dengan Xcode 9.2, saya membutuhkan file untuk kedua target agar diberi nama "googleServiceInfo.plist" tetapi ditempatkan di direktori yang berbeda, dengan direktori / file untuk setiap target ditentukan dalam "Build Phases", "Copy Bundle Resources".

Di atas bukanlah solusi pilihan saya, tetapi saya sebelumnya telah mencoba menggunakan nama file yang berbeda di sepanjang baris jawaban @ inidona, dikonversi ke Swift 4:

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

Sayangnya, ini tidak memperbaiki pesan kesalahan Firebase. Dalam pertanyaan ini: Firebase iOS SDK - Menggunakan file konfigurasi selain GoogleService-Info.plist menghasilkan peringatan konsol yang tampaknya telah diperbaiki oleh pengepos asli dengan memperbarui Firebase Pod tetapi saya belum mengonfirmasi hal ini.

djruss70.dll
sumber
1

Saya menyelesaikan ini dengan ini:

    #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
Arafin Russell
sumber
1

Jika beberapa dari Anda mengalami kesalahan dan Xcode mengeluh

"Beberapa perintah menghasilkan GoogleService-Info.plist"

setelah menerapkan respons @Knight Fighter , Anda mungkin ingin:

  • Centang Build Phases> Copy Bundle Resources
  • Filter untuk file bernama GoogleService-Info.plist
  • Hapus semua referensi yang Anda miliki, karena sudah disalin melalui skrip.
Luiz Dias
sumber