빌드 체계마다 다른 GoogleService-Info.plist 사용


109

prod와 스테이징을위한 빌드 체계 (2 개의 다른 번들 식별자 포함)를 사용하고 있으며 각 체계에 대해 별도의 GoogleService-Info.plist를 사용하려고합니다. GCM (및 goole 로그인)을 초기화 할 때 사용할 plist 파일을 수동으로 선택하는 방법이 있습니까? 아니면 plist 사용을 피하고 수동으로 설정하는 것이 가능합니까?

감사!


3
두 개의 다른 목표를 사용합니까? 그런 다음 다른 Copy Bundle Resources (빌드 단계에서)에 다른 파일 (동일한 이름)을 갖습니다.
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
내 하루 좋은 대답 저장
Siddh

1
이것이 정답입니다. 을 호출하더라도 Firebase Analytics는 앱의 루트 디렉토리에 plist 파일이 필요합니다 configure(options:). github.com/firebase/quickstart-ios/issues/5
Rob Bajorek

2
이것은 매우 좋은 해결책이며 답으로 받아 들여 져야합니다.
Luke Brandon Farrell

1
매우 가볍고 똑똑하고 훌륭한 대답입니다. 감사합니다!
gabuchan

1
당신은 건너 뛸 수 있습니다 @smileBot -r: 더 많은 정보를 원하시면 리눅스 / 유닉스에서 cp 명령
바실리 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서로 다른 위치에 두 개의 서로 다른 파일 파일 이 있습니까 아니면 다른 이름을 가진 두 개의 파일이있을 수 있습니다. 실제 파일 이름이 무엇이며 어디에 배치되어 있는지에 대한 자세한 정보를 제공해 주시겠습니까?
Varun Gupta 2016 년

1
GoogleService-Info-dev.plist라는 2 개의 파일이 있습니다. GoogleService-Info-live.plist이 코드를 사용하면 기본 GoogleService-Info-dev.plist 대신 조건문을 사용하는 대신 작업하려는 앱 whick 정보 파일을 알릴 수 있습니다. 파일간에 전환 할 대상 플래그
Essam Elmasry

응, AppDelegate에서
Essam Elmasry

1
'구성 파일을 찾을 수 없습니다 :'GoogleService-Info.plist '
orium

최근 문서에 "경고 :이 접근 방식은 일부 상황에서 Analytics 수집에 영향을 미칠 수 있습니다." firebase.google.com/docs/projects/multiprojects
Shingo Fukuyama

30

이 문서를 확인하십시오 : https://medium.com/@brunolemos/how-to-setup-a-different-firebase-project-for-debug-and-release-environments-157b40512164

Xcode에서 프로젝트 내에 두 개의 디렉토리 ( DebugRelease. GoogleService-Info.plist거기에 각 파일을 넣으십시오 .

AppDelegate.m, didFinishLaunchingWithOptions메서드 내부 에 코드를 입력합니다.

목표 -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
이것은 나를 위해 일했습니다. 이 폴더를 참조로 추가해야합니다. 그렇지 않으면 실제로 충돌이 발생합니다. 감사!
Eironeia

이 솔루션은 여전히 Analytics프레임 워크에 대한 문제를 해결하지 못하며 어느 .plist것이로드되고 있는지 알 수 없습니다 .
Lifely

@Bruno Lemos, 하나의 xcode 프로젝트에서 두 개의 Firebase 프로젝트를 동시에 사용할 수 있습니까? 하지 Debug& Release? 이 작업을 수행하려고 할 때 항상 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
위의 코드를 사용하면 서로 다른 위치에 GoogleService-Info.plist 파일이 두 개 있거나 이름이 다른 두 파일이있을 수 있습니다. 실제 파일 이름이 무엇이며 어디에 배치되어 있는지에 대한 자세한 정보를 제공해 주시겠습니까?
Varun Gupta 2016 년

4
configureWithOptions 호출 중에 로그에이 오류가 발생합니다.Could not locate configuration file: 'GoogleService-Info.plist'
Babken Vardanyan

14

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를 엉망으로 만들지 않는 두 가지 솔루션이 있습니다.

  1. 각 체계에 다른 대상을 사용하고의 각 버전을 GoogleService-Info.plist고유 한 대상 과 연결합니다 . Xcode의 오른쪽 에있는 File inspector 에서 Target Membership 을 참조하십시오 . 자세한 내용은이 질문을 참조하십시오 .

  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는 'upload-symbols'스크립트를 사용하여 dSYM 파일을 업로드하는 데 GoogleService-Info.plist 파일 만 사용할 수 있기 때문에이 솔루션은 완벽하게 작동합니다!
Alexey Galishnikov

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.plistDev 디렉터리에
복사합니다 . 마찬가지로 Prod 디렉터리 의 Firebase 프로덕션 환경에 해당하는 GoogleService-Info.plist를 복사합니다 . "필요한 경우 항목 복사"" 대상에 추가" 아래의 모든 대상 을 선택 취소하십시오 .

(1 단계 이미지 링크 (평판이 낮아 이미지를 추가 할 수 없음))

2 단계 :
Xcode 프로젝트 탐색기에서 앱 대상을 선택합니다. 상단의 빌드 단계 탭으로 전환 한 다음 새 실행 스크립트 단계 를 추가합니다 . 단계 이름을 'Setup 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 groupsAdd 여기에 이미지 설명 입력

그게 다야. 이제이 구조와 비슷한 것이 있어야합니다.

여기에 이미지 설명 입력

목표물을 만들 때 올바른 GoogleService-Info.plist것이 사용됩니다.


나를 위해 완벽하게 작동했습니다.
Şafak Gezer

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 질문을 확인하면 문제에 대한 자세한 정보 / 아이디어를 얻을 수 있습니다.


여기서 target은 동일한 프로젝트에 대해 다른 계획을 의미합니까? 질문을 읽은 후 대상이 동일한 대상에 대한 다른 빌드 체계가 아니라 완전히 다른 빌드 대상을 의미한다는 것을 수집했습니다.
Varun Gupta

1
그러나 각 체계에 대해 다른 구성을 가진 하나의 대상이 있다면 어떻게 될까요?
evya

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.