Crashlytics 发现无效的 API 密钥 [英] Crashlytics found an invalid API key

查看:30
本文介绍了Crashlytics 发现无效的 API 密钥的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我尝试使用 meta-data 标记的 value 作为字符串引用构建项目时,crashlytics 失败并显示以下错误:

Crashlytics 发现无效的 API 密钥:@string/crashlytics.检查 Crashlytics 插件以确保已成功添加应用程序!联系 support@crashlytics.com 寻求帮助.

不起作用

<元数据android:name="com.crashlytics.ApiKey"android:value="@string/crashlytics"/>

作品

<元数据android:name="com.crashlytics.ApiKey"android:value="1234567890..."/>

我想在 string.xml 中为我的 android 项目的不同 productFlavors 定义不同的键.

更新

写信给 crashlytics 支持后:

<块引用>

目前我们只能在构建时评估 AndroidManifest.xml,所以我们不查看任何字符串资源,因此我们只支持硬编码字符串.我一定会与您感兴趣的团队分享这一点,以便我们在未来的版本中考虑支持这一点.

解决方案

接受的解决方案只有在您使用 Crashlytics 的旧版本(我使用的是 v1.1.11)时才有效.如果您使用的是 Fabric SDK,您会注意到插件的任务发生了很大变化,下面的脚本不管用.也不再需要 API 秘密,因此您只需使用清单中的 <meta> 来指定 API 密钥以及在您的风格中定义的清单占位符:

  • build.gradle中:

    <块引用>

    flavor1 {...manifestPlaceholders = [crashlyticsApiKey: CRASHLYTICS_API_SECRET_HERE]...}

  • AndroidManifest.xml 中:

    <块引用>

    <代码>...<元数据android:name="com.crashlytics.ApiKey"android:value="${crashlyticsApiKey}"/>...

  • 还有另一种未公开的方法可以将 Crashlytics 密钥指定为此处注明,它是使用crashlytics.properties(在项目的根目录中)以指定该值以及 API 密钥:

    apiKey=YOUR_API_KEYapiSecret=YOUR_API_SECRET

    不幸的是,这不允许您简单地为每种风格指定不同的 crashlytics.properties,因为它需要位于项目的根目录中才能被 gradle 插件正确选择.这意味着您需要动态生成该文件.这个想法是在您的风味中添加键/秘密值作为自定义属性,并在构建时生成 crashlytics.properties,使用当前风味中的值填充文件.

    Android 模块中的 build.gradle 应该如下所示:

    <代码>...产品风味{风味 1 {...设置(crashlyticsApiKey",CRASHLYTICS_API_KEY_HERE)设置(crashlyticsApiSecret",CRASHLYTICS_API_SECRET_HERE)...}...}File crashlyticsProperties = new File("${project.projectDir.absolutePath}/crashlytics.properties")applicationVariants.all { 变体 ->variant.productFlavors.each { 风味 ->def variantSuffix = variant.name.capitalize()def generateResourcesTask = project.tasks.getByName("crashlyticsGenerateResources${variantSuffix}")def generatePropertiesTask = task("crashlyticsGenerateProperties${variantSuffix}") <<{属性属性=新属性()println "...复制 ${variant.name} 的 apiSecret"properties.put("apiSecret", flavor.crashlyticsApiSecret)println "...复制 ${variant.name} 的 apiKey"properties.put("apiKey", flavor.crashlyticsApiKey)properties.store(new FileWriter(crashlyticsProperties),"")}generateResourcesTask.dependsOn generatePropertiesTaskdef cleanResourcesTask = project.tasks.getByName("crashlyticsCleanupResourcesAfterUpload${variantSuffix}")cleanResourcesTask.doLast {println "...删除 crashlytics.properties"crashlyticsProperties.delete()}}}...

    基本上,脚本会在构建过程中挂钩并在 Crashlytics gradle 插件发挥其魔力之前生成/填充属性文件.

    When I am trying to build project with value of meta-data tag as a string reference, crashlytics fail with following error:

    Crashlytics found an invalid API key: @string/crashlytics. 
    Check the Crashlytics plugin to make sure that the application has been added successfully! 
    Contact support@crashlytics.com for assistance.
    

    Doesn't work

    <meta-data
        android:name="com.crashlytics.ApiKey"
        android:value="@string/crashlytics"/>
    

    Works

    <meta-data
        android:name="com.crashlytics.ApiKey"
        android:value="1234567890..."/>
    

    I am want to define different keys inside string.xml for different productFlavors of my android project.

    Update

    After writing to crashlytics support:

    Currently we only are able to evaluate the AndroidManifest.xml at build time so we don't look at any strings resources so we only support a hard coded string. I'll definitely share this with the team that you're interested so we can look into supporting this in a future release.

    解决方案

    Edit: The solution accepted is working only if you are using an old version of Crashlytics (I was using v1.1.11). If you are using Fabric SDK you will notice the tasks of the plugin have changed considerably and the script below will not work. Also the API secret is not needed anymore, therefore you can just use the <meta> in the manifest to specify the API key along with a manifest placeholder defined in your flavor:

    • in build.gradle:

      flavor1 {
          ...
          manifestPlaceholders = [crashlyticsApiKey: CRASHLYTICS_API_SECRET_HERE]
          ...
      }
      

    • in AndroidManifest.xml:

      ...
      <meta-data
          android:name="com.crashlytics.ApiKey"
          android:value="${crashlyticsApiKey}" />
      ...
      

    There is another undocumented way to specify the Crashlytics key as noted here, and it is to use the crashlytics.properties (in the root of your project) to specify that value along with the API secret:

    apiKey=YOUR_API_KEY
    apiSecret=YOUR_API_SECRET
    

    Unfortuntately this will not allow you to simply specify a different crashlytics.properties for each flavor, because it needs to be in the root of your project in order to be picked correctly by the gradle plugin. That means you need to generate that file dynamically. The idea is to add the key/secret values in your flavor as custom properties, and generate the crashlytics.properties at buildtime, using the values from the current flavor to fill the file.

    The build.gradle inside your android module should look like this:

    ...
    productFlavors {
    
        flavor1 {
            ...
            set("crashlyticsApiKey", CRASHLYTICS_API_KEY_HERE)
            set("crashlyticsApiSecret", CRASHLYTICS_API_SECRET_HERE)
            ...
        }
        ...
    }
    
    File crashlyticsProperties = new File("${project.projectDir.absolutePath}/crashlytics.properties")
    applicationVariants.all { variant ->
        variant.productFlavors.each { flavor ->
            def variantSuffix = variant.name.capitalize()
            def generateResourcesTask = project.tasks.getByName("crashlyticsGenerateResources${variantSuffix}")
            def generatePropertiesTask = task("crashlyticsGenerateProperties${variantSuffix}") << {
                Properties properties = new Properties()
                println "...copying apiSecret for ${variant.name}"
                properties.put("apiSecret", flavor.crashlyticsApiSecret)
                println "...copying apiKey for ${variant.name}"
                properties.put("apiKey", flavor.crashlyticsApiKey)
                properties.store(new FileWriter(crashlyticsProperties), "")
            }
            generateResourcesTask.dependsOn generatePropertiesTask
            def cleanResourcesTask = project.tasks.getByName("crashlyticsCleanupResourcesAfterUpload${variantSuffix}")
            cleanResourcesTask.doLast {
                println "...removing crashlytics.properties"
                crashlyticsProperties.delete()
            }
        }
    }
    ...
    

    Basically the script hooks in the building process and generates/fills the properties file just before the Crashlytics gradle plugin does its magic.

    这篇关于Crashlytics 发现无效的 API 密钥的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆