Ios 在新Firebase中,如何在xcode中使用多个配置文件?

Ios 在新Firebase中,如何在xcode中使用多个配置文件?,ios,xcode,firebase,Ios,Xcode,Firebase,嘿,我正在玩新的firebase iOS SDK,在我的项目中,我只有一个目标,我创建了两个配置,调试和发布,具有不同的绑定器标识符,但从firebase下载的配置文件似乎只支持一个绑定器标识符 那么有人知道如何在多包标识符xcode项目中使用firebase吗 谢谢 我已经实现了类似的东西,因为我已经为一个目标实现了两个方案,它们具有不同的bundle标识符。在我下面的例子中,我有两个不同的方案,一个用于UAT,一个用于PROD 创建两个GoogleService-Info.json文件,并将

嘿,我正在玩新的firebase iOS SDK,在我的项目中,我只有一个目标,我创建了两个配置,调试和发布,具有不同的绑定器标识符,但从firebase下载的配置文件似乎只支持一个绑定器标识符

那么有人知道如何在多包标识符xcode项目中使用firebase吗


谢谢

我已经实现了类似的东西,因为我已经为一个目标实现了两个方案,它们具有不同的bundle标识符。在我下面的例子中,我有两个不同的方案,一个用于UAT,一个用于PROD

创建两个GoogleService-Info.json文件,并将它们放入不同文件夹中的项目目录(而不是Xcode项目),例如

ROOT/config/UAT/GoogleService-Info.json
ROOT/config/PROD/GoogleService-Info.json
然后将这些文件添加到Xcode项目中,如下所示:

现在,您需要在构建阶段添加一个运行脚本。这需要在编译源代码阶段之前添加:

此运行脚本获取位于适当位置的json文件并将其复制到build app目录中,这意味着Firebase/Google将以与在单个标识符设置中识别文件相同的方式对其进行识别

isUAT=`expr "$GCC_PREPROCESSOR_DEFINITIONS" : ".*UAT=\([0-9]*\)"`

RESOURCE_PATH=${SRCROOT}/${PRODUCT_NAME}/config/PROD

if [ $isUAT = 1 ]; then
    RESOURCE_PATH=${SRCROOT}/${PRODUCT_NAME}/config/UAT
fi

BUILD_APP_DIR=${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app

echo "Copying all files under ${RESOURCE_PATH} to ${BUILD_APP_DIR}"
cp -v "${RESOURCE_PATH}/"* "${BUILD_APP_DIR}/"

我估计您也可以将同样的逻辑用于Google Analytics,它使用类似的json配置文件设置。

更新:请参阅Firebase官方文档

更新为更简单的解决方案:

  • 保持两个GoogleService-Info.plist的名称相同
  • 将一个GoogleService-Info.plist放在子文件夹中,说“staging”
  • 在Xcode中添加对这两个文件的引用,同时将它们链接到相应的目标
  • 只需在AppDelegate中使用FIRApp.configure(),即可

  • 我的第一次尝试没有解决问题:

    我将第二个GoogleService-Info.json重命名为其他名称,并使用以下代码从AppDelegate配置Firebase

    // Swift code
    #if STAGING
        let firebasePlistFileName = "GoogleService-Staging-Info"
    #else
        let firebasePlistFileName = "GoogleService-Info"
    #endif
    let firbaseOptions = FIROptions(contentsOfFile: NSBundle.mainBundle().pathForResource(firebasePlistFileName, ofType: "plist"))
    FIRApp.configureWithOptions(firbaseOptions)
    
    如果我运行暂存目标,我将收到Firebase关于“找不到配置文件:'GoogleService Info.plist'”的投诉。但它说“Firebase Analytics v.3300000已启动”

    正如我在Firebase仪表板上检查的那样,生产和登台应用程序都记录了传入的用户事件


    上述configureWithOptions方法没有在Firebase文档中记录,我通过检查其源代码找到了它。我不确定这样称呼会有什么负面影响。我很想听听其他的方法。

    如果您有一个目标,更好的方法就是正确地命名您的配置并按如下方式加载它们。似乎在UAT环境下工作良好 示例:Swift 3.0

        var fireBaseConfigFile = Bundle.main.path(forResource: "GoogleService-Info-PROD", ofType: "plist")
       #if UAT
           fireBaseConfigFile = Bundle.main.path(forResource: "GoogleService-Info-UAT", ofType: "plist")
       #endif
    
       guard let firOptions = FIROptions(contentsOfFile: fireBaseConfigFile) else {
           assert(false, "Failed to load Firebase config file")
           return
       }
    
       FIRApp.configure(with: firOptions)
    

    使用不同的名称将两个Google服务列表添加到您的项目中:

    然后,对于每个构建方案,选择编辑方案并为环境变量添加唯一值,如下所示:

    例如,另一个构建方案的build_FOR环境变量将设置为“DEV”

    然后,您将在App Delegate中检查此变量,并根据构建的方案配置FIRApp:

        let buildFor = ProcessInfo.processInfo.environment["BUILD_FOR"]! as String
        var firebasePlistFileName = "GoogleService-Info"
    
        if buildFor == "PROD" {
            firebasePlistFileName = "GoogleService-Prod-Info"
        }
    
        let firbaseOptions = FIROptions(contentsOfFile: Bundle.main.path(forResource: firebasePlistFileName, ofType: "plist"))
        FIRApp.configure(with: firbaseOptions!)
    

    我确实用不同的名称存储了2条谷歌服务信息:

    • GoogleService Info.plist
      用于生产
    • GoogleService Info Debug.plist
      用于开发
    然后转到构建阶段,添加新的运行脚本:

    if [ "${CONFIGURATION}" == "Release" ]; then
    cp -r "${PROJECT_DIR}/PathToYourGoogleServiceInfoFile/GoogleService-Info.plist" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/GoogleService-Info.plist"
    
    echo "Production plist copied"
    
    elif [ "${CONFIGURATION}" == "Debug" ]; then
    
    cp -r "${PROJECT_DIR}/PathToYourGoogleServiceInfoFile/GoogleService-Info-Debug.plist" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/GoogleService-Info.plist"
    
    echo "Development plist copied"
    fi
    

    使用Objective-C,在AppDeltage.m中:

    NSString *filePath;
    #ifdef DEBUG
      filePath = [[NSBundle mainBundle] pathForResource:@"GoogleService-Info-Debug" ofType:@"plist"];
    #else
      filePath = [[NSBundle mainBundle] pathForResource:@"GoogleService-Info-Production" ofType:@"plist"];
    #endif
    
      FIROptions *options = [[FIROptions alloc] initWithContentsOfFile:filePath];
      [FIRApp configureWithOptions:options];
    
    Firebase包括如何立即执行此操作。我在我的应用程序中使用了这种方法,效果非常好

    更具体地说,我在XCode中定义了一个自定义Swift标志“BUILD_TYPE”,并为每个方案定义了该标志的唯一值。然后,在我的AppDelegate中,我通过这个Swift标志值告诉Firebase在运行时要加载的
    GoogleService-\u__;.plist
    文件:

        let filePath = Bundle.main.path(forResource: "GoogleService-" + Bundle.main.infoDictionary!["BUILD_FLAVOR"] as! String, ofType: "plist")
        guard let fileopts = FirebaseOptions.init(contentsOfFile: filePath!) else {
            fatalError("Couldn't load config file")
        }
        FirebaseApp.configure(options: fileopts)
    

    我看到很多使用目标的响应,但如果您想根据方案进行区分,可以访问:

    编辑方案…>选择方案>生成>后期操作

    • 添加一个运行脚本
    • 从以下位置提供生成设置:(选择要创建的目标)
    • 添加以下脚本
    不要忘记将
    路径更改为\u GOOGLE\u PLISTS

    样本:

    最新语法用于为2个目标(2个Plist文件)配置firebase


    firebasePlistFileName变量只是根据当前配置(即开发或生产)获取PList名称。

    方案的目标是否不同,或者它们是否都在同一目标中?@IanBarber否我只有一个目标,我创建了两个配置,调试和发布,使用不同的绑定器标识符。如果您有不同的目标,则更新的答案有效。原来的答案对我不起作用。Firebase配置仍试图打开Google服务信息文件。谢谢FIRApp.configureWithOptions记录在这里:您的原始答案现在可以与最新版本的Firebase一起使用。如果有人感兴趣,这里有configureWithOptions文档::Firebase包括如何立即执行此操作。非常接近你所拥有的。非常感谢。Firebase官方文档对于一个目标应用程序是错误的,如果您重命名两个文件,他们的方法将无法工作。我还没有验证这一点,但如果Firebase现在可以做到这一点,我建议您这样做。请注意-例如,didFinishLauchingWithOptions函数,但不要在override init方法中执行此操作,除非您想中断Swizzling这是我第一次发现的最简单的方法,并且工作得非常完美。我就这个方法写了一个简短的要点:Thank you@TheiOSChap,you make my Day you不应该在运行时做那种事情,因为它会影响您的生产分析。这个解决方案的问题是需要在应用程序包中同时包含这两个文件。我建议使用这种方法,但将prod文件命名为“GoogleService Info.plist”,以便它与默认值匹配,并且不会影响产品分析。非常感谢。在ca
    PATH_TO_GOOGLE_PLISTS="${PROJECT_DIR}/MVCVMRC/Supporting Files/FirebasePlist"
    
    cp -r "$PATH_TO_GOOGLE_PLISTS/Brazil/GoogleService-Info-preprod.plist" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/GoogleService-Info.plist"
    
    func configureFirebase() {
            let firebasePlistFileName = ConfigurationManager.sharedManager().firebasePlistName()
            if let path = Bundle.main.path(forResource: firebasePlistFileName, ofType: "plist") {
                if let firbaseOptions = FirebaseOptions(contentsOfFile: path) {
                    FirebaseApp.configure(options: firbaseOptions)
                }
            }
        }