Search code examples
androidfirebasereact-nativecrashlyticsgoogle-fabric

Android project build failure while setting up Firebase+Crashlytics


I have a question about Firebase+Crashlytics+Android. On Android Studio I am getting the following error:

org.gradle.api.GradleException: Crashlytics Developer Tools error. com.crashlytics.tools.android.exception.PluginException: Crashlytics Developer Tools error. java.lang.illegalArgumentException: Crashlytics found an invalid API key: null.

I have followed the instructions here and here. As I understand it, I don’t need to set the apiKey in the project and Firebase will take care of this. But the project build still fails and complains. I haven’t been able to find appropriate help online about this. The documentation on Crashlytics also seems to be in beta on Firebase.

The closest I’ve gotten is someone suggesting that I set up a fabric.properties file with an apiKey field set. But on the Firebase->Crashlytics dashboard I can’t find this API key.

Does anyone have an idea how this can be resolved?

Note 1: I don’t have admin access to the project on Firebase. Maybe the key is only visible to them?

Note 2: It’s actually a react-native project. But that shouldn’t really make a difference since this is purely a native-side configuration.

Edit: Adding app/build.gradle on request:

apply plugin: "com.android.application"
apply plugin: "io.fabric"
apply from: project(':react-native-config').projectDir.getPath() + "/dotenv.gradle" // MANUAL CHANGE

import com.android.build.OutputFile
def enableSeparateBuildPerCPUArchitecture = false
def enableProguardInReleaseBuilds = false

android {

    compileSdkVersion 23
    buildToolsVersion "23.0.3"

    defaultConfig {
        applicationId "com.my.app"
        minSdkVersion 16
        targetSdkVersion 23
        versionCode 4
        versionName "1.0"
        ndk {
            abiFilters "armeabi-v7a", "x86"
        }
    }
    splits {
        abi {
            reset()
            enable enableSeparateBuildPerCPUArchitecture
            universalApk false  // If true, also generate a universal APK
            include "armeabi-v7a", "x86"
        }
    }

    buildTypes {
        release {
            minifyEnabled enableProguardInReleaseBuilds
            proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
            signingConfig signingConfigs.release
        }
    }

    applicationVariants.all { variant ->
        variant.outputs.each { output ->

            def versionCodes = ["armeabi-v7a":1, "x86":2]
            def abi = output.getFilter(OutputFile.ABI)
            if (abi != null) {  // null for the universal-debug, universal-release variants
                output.versionCodeOverride =
                        versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
            }
        }
    }
}

dependencies {
    compile(project(':react-native-firebase')) {
        transitive = false
    }
    compile project(':react-native-push-notification')
    compile project(':react-native-google-analytics-bridge')
    compile project(':react-native-device-info')
    compile (project(':react-native-google-analytics-bridge')) {
        exclude group: 'com.google.android.gms'
    }

    compile (project(':react-native-device-info')) {
        exclude group: 'com.google.android.gms'
    }

    compile (project(':react-native-push-notification')) {
        exclude group: 'com.google.android.gms'
    }
    compile(project(':react-native-maps')) {
        exclude group: 'com.google.android.gms'
    }
    compile project(':react-native-config')
    compile project(':react-native-vector-icons')

    compile('com.crashlytics.sdk.android:crashlytics:2.9.1@aar') {
        transitive = true
    }

    // Forcing version 11.8.0 of play-services because that's the version firebase needs for all its features
    compile ("com.google.android.gms:play-services-maps:11.8.0") {
        force = true
    }
    compile ("com.google.android.gms:play-services-gcm:11.8.0") {
        force = true
    }
    //Analytics
    compile ('com.google.firebase:firebase-core:11.8.0') {
        force = true
    }
    //Cloud Messaging
    compile ('com.google.firebase:firebase-messaging:11.8.0') {
        force = true
    }
    //Authentication
    compile ('com.google.firebase:firebase-auth:11.8.0') {
        force = true
    }

    compile fileTree(dir: "libs", include: ["*.jar"])
    compile "com.android.support:appcompat-v7:23.0.1"
    compile "com.facebook.react:react-native:+"  // From node_modules
}

task copyDownloadableDepsToLibs(type: Copy) {
    from configurations.compile
    into 'libs'
}

Solution

  • Mike from Firebase here. If you are an existing Firebase customer, using Crashlytics via Fabric, then here's what your files should look like. Note: We don't have official React Native support, so I'm not including any of those files. I don't think it's relevant given the native implementation here, but trying to be clear :)

    Project build.gradle:

    // Top-level build file where you can add configuration options common to all sub-projects/modules.
    
    buildscript {
        repositories {
            jcenter()
            maven {
                url 'https://maven.fabric.io/public'
            }
        }
        dependencies {
            classpath 'com.android.tools.build:gradle:3.0.1'
            classpath 'com.google.gms:google-services:3.2.0' // google-services plugin
            classpath 'io.fabric.tools:gradle:1.25.1'
    
    
            // NOTE: Do not place your application dependencies here; they belong
            // in the individual module build.gradle files
        }
    }
    
    allprojects {
        repositories {
            jcenter()
            maven {
                url 'https://maven.google.com/'
            }
        }
    
    
    }
    
    task clean(type: Delete) {
        delete rootProject.buildDir
    }
    

    App's build.gradle:

    buildscript {
        repositories {
            maven { url 'https://maven.fabric.io/public' }
        }
    
        dependencies {
            classpath 'io.fabric.tools:gradle:1.25.1'
    
        }
    }
    apply plugin: 'com.android.application'
    apply plugin: 'io.fabric'
    
    repositories {
        maven { url 'https://maven.fabric.io/public' }
        maven {url 'https://maven.google.com'} // Google's Maven repository}
    
    }
    
    
    android {
        compileSdkVersion 25
        buildToolsVersion "26.0.2"
        defaultConfig {
            applicationId "com.example.mbonnell.myapplication"
            minSdkVersion 15
            targetSdkVersion 25
            versionCode 1
            versionName "1.0"
            testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        }
        buildTypes {
            release {
                minifyEnabled true
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
            debug {
                minifyEnabled false
    
            }
        }
    }
    
    dependencies {
        compile fileTree(dir: 'libs', include: ['*.jar'])
        androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
            exclude group: 'com.android.support', module: 'support-annotations'
        })
        compile 'com.android.support:appcompat-v7:25.3.0'
        testCompile 'junit:junit:4.12'
        compile('com.crashlytics.sdk.android:crashlytics:2.9.1@aar') {
            transitive = true;
        }
        compile('com.google.firebase:firebase-core:11.8.0')
    
    
    }
    
    apply plugin: 'com.google.gms.google-services'
    

    AndroidManifest.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.mbonnell.myapplication">
    
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
            <activity android:name=".MainActivity">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
          <!--<meta-data-->
                <!--android:name="io.fabric.ApiKey"-->
                <!--android:value="YourApiKey" />-->
        </application>
    
        <uses-permission android:name="android.permission.INTERNET" />
    </manifest>
    

    MainActivity.java:

    There should be some implementation of Firebase. To keep thing simple, I'm initializing Firebase analytics:

    public class MainActivity extends AppCompatActivity {
    
        private FirebaseAnalytics mFirebaseAnalytics;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);
            setContentView(R.layout.activity_main);
    }