Search code examples
javaandroidfirebasereact-nativebuild

Type io.invertase.firebase.BuildConfig is defined multiple times


I am trying to build a react native application in VSCode. I am getting the following error when I try to build the app. I keep getting the following issue while getting the build complete. I tried to change the firebase version and Gradle updates but did not work.

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:mergeDexRelease'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.Workers$ActionFacade
   > com.android.builder.dexing.DexArchiveMergerException: Error while merging dex archives: 
     Learn how to resolve the issue at https://developer.android.com/studio/build/dependencies#duplicate_classes.
     Type io.invertase.firebase.BuildConfig is defined multiple times: /path/node_modules/@react-native-firebase/app/android/build/.transforms/7d2ce1f5b074ed872b704906f3d41618/classes/classes.dex, /path/node_modules/react-native-firebase/android/build/.transforms/0b00760c914c9cf3e84f7c87e9135514/classes/classes.dex

BUILD FAILED in 3m 50s

`app/build.gradle` looks as follows
apply plugin: "com.android.application"
apply plugin: 'com.google.gms.google-services'

import com.android.build.OutputFile;
// import androidx.core.content.FileProvider;

project.ext.react = [
    enableHermes: false,  // clean and rebuild if changing
]

apply from: "../../node_modules/react-native/react.gradle"

def jscFlavor = 'org.webkit:android-jsc:+'

def enableHermes = project.ext.react.get("enableHermes", false);

android {
    compileSdkVersion rootProject.ext.compileSdkVersion

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    defaultConfig {
        applicationId "com.odotime"
        minSdkVersion rootProject.ext.minSdkVersion
        targetSdkVersion rootProject.ext.targetSdkVersion
        versionCode 40
        versionName "1.41"
        multiDexEnabled true
    }
    splits {
        abi {
            reset()
            enable enableSeparateBuildPerCPUArchitecture
            universalApk false  // If true, also generate a universal APK
            include "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
        }
    }
    signingConfigs {
        debug {
            storeFile file('debug.keystore')
            storePassword 'android'
            keyAlias 'androiddebugkey'
            keyPassword 'android'
        }
        release {
            if (project.hasProperty('MYAPP_UPLOAD_STORE_FILE')) {
                storeFile file(MYAPP_UPLOAD_STORE_FILE)
                storePassword MYAPP_UPLOAD_STORE_PASSWORD
                keyAlias MYAPP_UPLOAD_KEY_ALIAS
                keyPassword MYAPP_UPLOAD_KEY_PASSWORD
            }
        }
    }
    buildTypes {
        debug {
            signingConfig signingConfigs.debug
        }
        release {
            // Caution! In production, you need to generate your own keystore file.
            // see https://reactnative.dev/docs/signed-apk-android.
            signingConfig signingConfigs.debug
            minifyEnabled enableProguardInReleaseBuilds
            proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
            signingConfig signingConfigs.release
        }
    }

    // applicationVariants are e.g. debug, release
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            // For each separate APK per architecture, set a unique version code as described here:
            // https://developer.android.com/studio/build/configure-apk-splits.html
            def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4]
            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 {
    implementation fileTree(dir: "libs", include: ["*.jar"])
    //noinspection GradleDynamicVersion
    implementation "com.facebook.react:react-native:+"  // From node_modules

    // Import the Firebase BoM
    implementation platform('com.google.firebase:firebase-bom:28.0.1') 
    
    compile project(':react-native-sms-retriever')
    
    // Declare the dependency for the Firebase SDK for Google Analytics
    implementation 'com.google.firebase:firebase-analytics:18.0.3'

    implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'

    implementation 'com.android.support:multidex:1.0.3'
    implementation "com.android.support:support-v4:22.1.0"
    implementation 'com.android.support:design:27.1.0'

    implementation project(':react-native-push-notification')

    debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") {
      exclude group:'com.facebook.fbjni'
    }

    debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
        exclude group:'com.facebook.flipper'
        exclude group:'com.squareup.okhttp3', module:'okhttp'
    }

    debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") {
        exclude group:'com.facebook.flipper'
    }

    if (enableHermes) {
        def hermesPath = "../../node_modules/hermes-engine/android/";
        debugImplementation files(hermesPath + "hermes-debug.aar")
        releaseImplementation files(hermesPath + "hermes-release.aar")
    } else {
        implementation jscFlavor
    }
}

// Run this once to be able to run the application with BUCK
// puts all compile dependencies into folder libs for BUCK to use
task copyDownloadableDepsToLibs(type: Copy) {
    from configurations.compile
    into 'libs'
}

apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)

package.json as follows

"dependencies": {
    "@capacitor/android": "^3.6.0",
    "@capacitor/core": "^3.6.0",
    "@react-native-community/art": "^1.2.0",
    "@react-native-community/async-storage": "^1.12.0",
    "@react-native-community/masked-view": "^0.1.10",
    "@react-native-community/netinfo": "^5.9.6",
    "@react-native-community/push-notification-ios": "^1.8.0",
    "@react-native-firebase/app": "^12.1.0",
    "@react-native-firebase/messaging": "^12.1.0",
    "@react-navigation/bottom-tabs": "^5.8.0",
    "@react-navigation/material-bottom-tabs": "^5.2.16",
    "@react-navigation/native": "^5.7.3",
    "@react-navigation/stack": "^5.9.0",
    "amazon-cognito-identity-js": "^4.3.3",
    "aws-amplify": "^3.0.23",
    "axios": "^0.20.0",
    "cordova-plugin-androidx-adapter": "^1.1.3",
    "i18n-js": "^3.7.1",
    "jetifier": "^2.0.0",
    "lodash.memoize": "^4.1.2",
    "moment": "^2.29.1",
    "moment-range": "^4.0.2",
    "moment-timezone": "^0.5.33",
    "react": "16.13.1",
    "react-devtools": "^4.8.2",
    "react-native": "0.63.2",
    "react-native-calendars": "^1.343.0",
    "react-native-contacts": "^6.0.3",
    "react-native-country-picker-modal": "^2.0.0",
    "react-native-date-picker": "^3.2.3",
    "react-native-drop-shadow": "^0.0.2",
    "react-native-dropdown-picker": "^3.7.1",
    "react-native-email-link": "^1.11.3",
    "react-native-firebase": "^5.6.0",
    "react-native-gesture-handler": "^1.7.0",
    "react-native-hyperlinked-text": "^1.0.2",
    "react-native-image-picker": "^2.3.4",
    "react-native-loading-spinner-overlay": "^1.1.0",
    "react-native-localize": "^2.0.1",
    "react-native-paper": "^4.1.0",
    "react-native-pie": "^1.1.2",
    "react-native-push-notification": "^7.3.1",
    "react-native-raw-bottom-sheet": "^2.2.0",
    "react-native-reanimated": "^1.13.0",
    "react-native-safe-area-context": "^3.1.6",
    "react-native-screens": "^2.10.1",
    "react-native-sectioned-multi-select": "^0.8.1",
    "react-native-simple-radio-button": "^2.7.4",
    "react-native-simple-toast": "^1.1.2",
    "react-native-sms-retriever": "^1.1.1",
    "react-native-svg-transformer": "^0.14.3",
    "react-native-switch-selector": "^2.0.6",
    "react-native-vector-icons": "^7.1.0",
    "react-redux": "^7.2.1",
    "redux": "^4.0.5",
    "redux-form": "^8.3.6",
    "redux-persist": "^6.0.0",
    "redux-persist-transform-filter": "0.0.20",
    "redux-saga": "^1.1.3",
    "reselect": "^4.0.0",
    "save": "^2.4.0",
    "toggle-switch-react-native": "^2.3.0"
  },
  "devDependencies": {
    "@babel/core": "^7.8.4",
    "@babel/runtime": "^7.8.4",
    "@capacitor/cli": "^3.6.0",
    "@react-native-community/eslint-config": "^1.1.0",
    "babel-jest": "^25.1.0",
    "eslint": "^6.8.0",
    "jest": "^25.1.0",
    "metro-react-native-babel-preset": "^0.59.0",
    "react-test-renderer": "16.13.1",
    "remote-redux-devtools": "^0.5.16"
  },

Solution

  • This happens when we try to have multiple packages that overlap when they compile together. This is a very common issue when we are using some older versions of packages.

    This specific instance occurs when the user tries to install and use @react-native-firebase/app and react-native-firebase. I used an older version of react-native-firebase for push notifications but as of my knowledge and experience @react-native-firebase/app covers that. So removing react-native-firebase and doing an npm i and then building worked for me.

    In general cases, we have to check each package by package and check which one is causing the overlap and either remove it or find some alternatives for the package in the development and build.