transistorsoft / react-native-background-geolocation

Sophisticated, battery-conscious background-geolocation with motion-detection
http://shop.transistorsoft.com/pages/react-native-background-geolocation
MIT License
2.66k stars 425 forks source link

NoClassDefFoundError: Failed resolution of: Lcom/google/android/gms/location/ActivityTransitionEvent #704

Closed unlucio closed 5 years ago

unlucio commented 5 years ago

Your Environment

Expected Behavior

My app should run and not crash at start

Actual Behavior

Asap the app starts, it crashes with the included NoClassDefFoundError error

Steps to Reproduce

I'm afraid this might be my very specific problem

Context

Pretty old codebase and we need to remove a couple of entry in the menu (so I',m not actually changing anything of the code base, just commenting out some lines)

Debug logs

Hello, I'm dealing with a RN application using this package, and my problem is android. Disclaimer: I just inherited the codebase so I'm just as baffled by reading "react-native": "=0.41" in the package.json and unfortunately I'm not in the position of updating it at this time.

Anyway at 1st the app didn't compile at all, reinstalling the module and following the manual instructions: https://github.com/transistorsoft/react-native-background-geolocation/blob/master/help/INSTALL-ANDROID.md did get the app to compile, but as soon as it gets installed and booted on a device or simulator the app crashes with the above error. Searching the internet I tried a number of suggestions and possible work arounds: checking SDK and google service's versions, reinstalling https://github.com/transistorsoft/react-native-background-fetch but nothing I found really helped (at most the all stopped compiling a couple of times 😕) I suspect my problem might come form com.google.android.gms:play-services-location, but I'm banging my head right now and I could really use some ideas.

Here's the app's gradle configuration:

android/settings.gradle:

rootProject.name = 'myapp'

include ':react-native-autoheight-webview'
project(':react-native-autoheight-webview').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-autoheight-webview/android')
include ':react-native-network-info'
project(':react-native-network-info').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-network-info/android')
include ':react-native-social-share'
project(':react-native-social-share').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-social-share/android')
include ':react-native-background-geolocation'
project(':react-native-background-geolocation').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-background-geolocation/android')
include ':react-native-autoheight-webview'
project(':react-native-autoheight-webview').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-autoheight-webview/android')
include ':react-native-brightcove-bridge'
project(':react-native-brightcove-bridge').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-brightcove-bridge/android')

include ':react-native-social-share'
project(':react-native-social-share').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-social-share/android')
include ':react-native-autoheight-webview'
project(':react-native-autoheight-webview').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-autoheight-webview/android')
include ':react-native-brightcove-bridge'
project(':react-native-brightcove-bridge').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-brightcove-bridge/android')
include ':react-native-social-share'
project(':react-native-social-share').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-social-share/android')
include ':react-native-background-geolocation'
project(':react-native-background-geolocation').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-background-geolocation/android')
include ':react-native-background-fetch'
project(':react-native-background-fetch').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-background-fetch/android')
include ':react-native-autoheight-webview'
project(':react-native-autoheight-webview').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-autoheight-webview/android')
include ':react-native-brightcove-bridge'
project(':react-native-brightcove-bridge').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-brightcove-bridge/android')
include ':react-native-social-share'
project(':react-native-social-share').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-social-share/android')
include ':react-native-autoheight-webview'
project(':react-native-autoheight-webview').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-autoheight-webview/android')
include ':react-native-social-share'
project(':react-native-social-share').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-social-share/android')
include ':react-native-autoheight-webview'
project(':react-native-autoheight-webview').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-autoheight-webview/android')
include ':react-native-social-share'
project(':react-native-social-share').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-social-share/android')
include ':react-native-autoheight-webview'
project(':react-native-autoheight-webview').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-autoheight-webview/android')
include ':react-native-social-share'
project(':react-native-social-share').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-social-share/android')
include ':react-native-social-share'
project(':react-native-social-share').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-social-share/android')

include ':react-native-code-push'
project(':react-native-code-push').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-code-push/android/app')
include ':react-native-branch', ':app'
project(':react-native-branch').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-branch/android')
include ':react-native-google-signin'
project(':react-native-google-signin').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-google-signin/android')
include ':react-native-segment-io-analytics'
project(':react-native-segment-io-analytics').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-segment-io-analytics/android')
include ':react-native-vector-icons'
project(':react-native-vector-icons').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-vector-icons/android')
include ':react-native-svg'
project(':react-native-svg').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-svg/android')
include ':react-native-linear-gradient'
project(':react-native-linear-gradient').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-linear-gradient/android')
include ':react-native-device-info'
project(':react-native-device-info').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-device-info/android')
include ':react-native-config'
project(':react-native-config').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-config/android')
include ':react-native-network-info'
project(':react-native-network-info').projectDir = new File(settingsDir, '../node_modules/react-native-network-info/android')

android/build.gradle:

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        jcenter()
        google()
        mavenCentral()
    }
    dependencies {
        // classpath 'com.android.tools.build:gradle:2.3.3'
        classpath 'com.android.tools.build:gradle:3.1.4'
        classpath 'com.google.gms:google-services:3.1.1'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
    ext {
        googlePlayServicesLocationVersion = "16.0.0"
    }
}

subprojects {
    afterEvaluate {project ->
        if (project.hasProperty("android")) {
            android {
                compileSdkVersion 28
                // buildToolsVersion '26.0.2'
            }
        }
    }
}

allprojects {
    repositories {
        mavenLocal()
        jcenter()
        maven {
            // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
            url "$rootDir/../node_modules/react-native/android"
        }
        maven {
            url "http://maven.batch.com/release"
        }
        maven {
           url 'https://maven.google.com'
        }
        maven {
            url "$rootDir/../node_modules/react-native-background-geolocation/android/libs"
        }
        maven {
           url "$rootDir/../node_modules/react-native-background-fetch/android/libs"
        }
        google()
    }

    configurations.all {
        resolutionStrategy {
                force 'com.squareup.okhttp3:okhttp:3.4.1'
                eachDependency { DependencyResolveDetails details ->
                if (details.requested.group == 'com.facebook.react' && details.requested.name == 'react-native') {
                    def file = new File("$rootDir/../node_modules/react-native/package.json")
                    def version = new groovy.json.JsonSlurper().parseText(file.text).version
                    details.useVersion version
                }
            }
        }
    }
}

android/app/build.gradle

apply plugin: "com.android.application"

import com.android.build.OutputFile

apply from: project(':react-native-config').projectDir.getPath() + "/dotenv.gradle"
apply from: "../../node_modules/react-native/react.gradle"
apply from: "../../node_modules/react-native-code-push/android/codepush.gradle"

project.ext.react = [
        bundleInDefaultConfigDebug: true,
        bundleInDefaultConfigRelease: true,
        jsBundleDirDefaultConfigDebug: "$buildDir/intermediates/assets/defaultConfig/debug",
        jsBundleDirDefaultConfigRelease: "$buildDir/intermediates/assets/defaultConfig/release",
        bundleInInstabugDebug: true,
        bundleInInstabugRelease: true,
        nodeExecutableAndArgs : ["/usr/local/bin/node"]
]

/**
 * Set this to true to create two separate APKs instead of one:
 *   - An APK that only works on ARM devices
 *   - An APK that only works on x86 devices
 * The advantage is the size of the APK is reduced by about 4MB.
 * Upload all the APKs to the Play Store and people will download
 * the correct one based on the CPU architecture of their device.
 */
def enableSeparateBuildPerCPUArchitecture = false

/**
 * Run Proguard to shrink the Java bytecode in release builds.
 */
def enableProguardInReleaseBuilds = false

android {
    compileSdkVersion 26
    buildToolsVersion "26.0.2"

    dexOptions {
        javaMaxHeapSize "2g"
    }

    defaultConfig {
        applicationId "my.app.id"
        versionCode 807
        versionName "1.3.4"
        minSdkVersion 16
        targetSdkVersion 22
        ndk {
            abiFilters "armeabi-v7a", "x86"
        }
        resValue "string", "build_config_package", "com.qa.ppl"
        multiDexEnabled true
    }
    signingConfigs {
        debug {
            storeFile file(MYAPP_RELEASE_STORE_FILE)
            storePassword MYAPP_RELEASE_STORE_PASSWORD
            keyAlias MYAPP_RELEASE_KEY_ALIAS
            keyPassword MYAPP_RELEASE_KEY_PASSWORD
        }
        release {
            storeFile file(MYAPP_RELEASE_STORE_FILE)
            storePassword MYAPP_RELEASE_STORE_PASSWORD
            keyAlias MYAPP_RELEASE_KEY_ALIAS
            keyPassword MYAPP_RELEASE_KEY_PASSWORD
        }
    }
    splits {
        abi {
            reset()
            enable enableSeparateBuildPerCPUArchitecture
            universalApk false  // If true, also generate a universal APK
            include "armeabi-v7a", "x86"
        }
    }
    buildTypes {
        debug {
            manifestPlaceholders = [excludeSystemAlertWindowPermission: "false"]
        }
        release {
            manifestPlaceholders = [excludeSystemAlertWindowPermission: "true"]
            minifyEnabled enableProguardInReleaseBuilds
            proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
            signingConfig signingConfigs.release
        }
        qa {
            initWith 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:
            // http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits
            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
            }
        }
    }
}

repositories {
    flatDir {
        dirs "../../node_modules/react-native-background-geolocation/android/libs"
    }
    maven {
        url 'http://repo.brightcove.com/releases'
    }
}

dependencies {
    // api 'com.google.android.gms:play-services-location:15.0.1'
    // compileOnly "com.google.android.gms:play-services-location:15.0.1"
    // runtimeOnly 'com.google.android.gms:play-services-location:11.8.0'
    compile project(':react-native-social-share')
    compile (project(':react-native-background-geolocation')) {
        exclude group: 'com.google.android.gms'
    }
    compile project(':react-native-background-fetch')
    compile project(':react-native-code-push')
    compile project(':react-native-branch')
    compile (project(':react-native-google-signin')) {
        exclude group: 'com.google.android.gms'
    }
    compile (project(':react-native-brightcove-bridge')) {
        exclude group: 'com.google.android.gms'
    }
    compile "com.mixpanel.android:mixpanel-android:4.+"
    compile 'com.google.firebase:firebase-messaging:11.8.0'
    // compile 'com.batch.android:batch-sdk:1.6+'
    compile 'com.batch.android:batch-sdk:1.13.0'
    compile 'com.android.support:recyclerview-v7:27.0.2'
    compile 'com.android.support:multidex:1.0.0'
    compile project(':react-native-segment-io-analytics')
    // compile(name: 'tslocationmanager', ext: 'aar')
    compile project(':react-native-vector-icons')
    compile project(':react-native-svg')
    compile project(':react-native-linear-gradient')
    // compile "com.android.support:appcompat-v7:27.0.2"
    compile "com.android.support:appcompat-v7:28.0.0"
    compile "com.android.support:support-core-utils:27.0.2"
    compile (project(':react-native-device-info')) {
        exclude group: 'com.google.android.gms'
    }
    compile project(':react-native-config')
    compile fileTree(dir: "libs", include: ["*.jar"])
    compile (project(':react-native-network-info')) {
        exclude group: 'com.google.android.gms'
    }
    compile 'com.google.android.gms:play-services-auth:11.8.0' // should be at least 9.0.0
    compile(project(":react-native-google-signin")){
        exclude group: "com.google.android.gms" // very important
    }
    compile 'com.android.support:multidex:1.0.1'
    compile 'com.google.android.gms:play-services:11.8.0' 
    compile ("com.google.android.gms:play-services-base:11.8.0") {
        force = true;
    }
    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;
    }
    compile ("com.google.android.gms:play-services-location:11.8.0") {
        force = true;
    }
    compile 'com.brightcove.player:exoplayer:4.+'
}

// 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 plugin: 'com.google.gms.google-services'
unlucio commented 5 years ago

I got it working bumping all the "google's stuff" to 12.0.1

christocracy commented 5 years ago

That’s right, but latest play-services:Location is 16.0.0.

Btw, you don’t need to do all that exclude group nonsense anymore. Most plugin expose a Gradle ext var for you to configure google versions.

Eg, this plugin exposes googlePlayServicesLocationVersion var.

unlucio commented 5 years ago

Eg, this plugin exposes googlePlayServicesLocationVersion var. which I dully set:

ext {
googlePlayServicesLocationVersion = "16.0.0"
}

but didn't help :P

christocracy commented 5 years ago

Post your current gradle files once again:

unlucio commented 5 years ago

this is the current state of: android/app/build.gradle everything else is the same as posted before

apply plugin: "com.android.application"

import com.android.build.OutputFile

apply from: project(':react-native-config').projectDir.getPath() + "/dotenv.gradle"
apply from: "../../node_modules/react-native/react.gradle"
apply from: "../../node_modules/react-native-code-push/android/codepush.gradle"

project.ext.react = [
        bundleInDefaultConfigDebug: true,
        bundleInDefaultConfigRelease: true,
        jsBundleDirDefaultConfigDebug: "$buildDir/intermediates/assets/defaultConfig/debug",
        jsBundleDirDefaultConfigRelease: "$buildDir/intermediates/assets/defaultConfig/release",
        bundleInInstabugDebug: true,
        bundleInInstabugRelease: true,
        nodeExecutableAndArgs : ["/usr/local/bin/node"]
]

/**
 * Set this to true to create two separate APKs instead of one:
 *   - An APK that only works on ARM devices
 *   - An APK that only works on x86 devices
 * The advantage is the size of the APK is reduced by about 4MB.
 * Upload all the APKs to the Play Store and people will download
 * the correct one based on the CPU architecture of their device.
 */
def enableSeparateBuildPerCPUArchitecture = false

/**
 * Run Proguard to shrink the Java bytecode in release builds.
 */
def enableProguardInReleaseBuilds = false

android {
    purgeBackgroundGeolocationDebugResources(applicationVariants)
    compileSdkVersion 26
    buildToolsVersion "26.0.2"

    dexOptions {
        javaMaxHeapSize "2g"
    }

    defaultConfig {
        applicationId "io.people.datacontroller.prod"
        versionCode 807
        versionName "1.3.4"
        minSdkVersion 16
        targetSdkVersion 22
        ndk {
            abiFilters "armeabi-v7a", "x86"
        }
        resValue "string", "build_config_package", "com.qa.ppl"
        multiDexEnabled true
    }
    signingConfigs {
        debug {
            storeFile file(MYAPP_RELEASE_STORE_FILE)
            storePassword MYAPP_RELEASE_STORE_PASSWORD
            keyAlias MYAPP_RELEASE_KEY_ALIAS
            keyPassword MYAPP_RELEASE_KEY_PASSWORD
        }
        release {
            storeFile file(MYAPP_RELEASE_STORE_FILE)
            storePassword MYAPP_RELEASE_STORE_PASSWORD
            keyAlias MYAPP_RELEASE_KEY_ALIAS
            keyPassword MYAPP_RELEASE_KEY_PASSWORD
        }
    }
    splits {
        abi {
            reset()
            enable enableSeparateBuildPerCPUArchitecture
            universalApk false  // If true, also generate a universal APK
            include "armeabi-v7a", "x86"
        }
    }
    buildTypes {
        debug {
            manifestPlaceholders = [excludeSystemAlertWindowPermission: "false"]
        }
        release {
            manifestPlaceholders = [excludeSystemAlertWindowPermission: "true"]
            minifyEnabled enableProguardInReleaseBuilds
            proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
            signingConfig signingConfigs.release
        }
        qa {
            initWith 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:
            // http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits
            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
            }
        }
    }
}

repositories {
    flatDir {
        dirs "../../node_modules/react-native-background-geolocation/android/libs"
    }
    maven {
        url 'http://repo.brightcove.com/releases'
    }
}

dependencies {
    compile project(':react-native-network-info')
    compile project(':react-native-google-signin')
    compile project(':react-native-device-info')
    compile project(':react-native-brightcove-bridge')
    compile project(':react-native-background-geolocation')
    compile project(':react-native-autoheight-webview')
    // api 'com.google.android.gms:play-services-location:15.0.1'
    // compileOnly "com.google.android.gms:play-services-location:15.0.1"
    // runtimeOnly 'com.google.android.gms:play-services-location:12.0.1'
    compile project(':react-native-social-share')
    compile (project(':react-native-background-geolocation')) {
        exclude group: 'com.google.android.gms'
    }
    compile project(':react-native-background-fetch')
    compile project(':react-native-code-push')
    compile project(':react-native-branch')
    compile (project(':react-native-google-signin')) {
        exclude group: 'com.google.android.gms'
    }
    compile (project(':react-native-brightcove-bridge')) {
        exclude group: 'com.google.android.gms'
    }
    compile "com.mixpanel.android:mixpanel-android:4.+"
    compile 'com.google.firebase:firebase-messaging:12.0.1'
    // compile 'com.batch.android:batch-sdk:1.6+'
    compile 'com.batch.android:batch-sdk:1.13.0'
    compile 'com.android.support:recyclerview-v7:27.0.2'
    compile 'com.android.support:multidex:1.0.0'
    compile project(':react-native-segment-io-analytics')
    // compile(name: 'tslocationmanager', ext: 'aar')
    compile project(':react-native-vector-icons')
    compile project(':react-native-svg')
    compile project(':react-native-linear-gradient')
    // compile "com.android.support:appcompat-v7:27.0.2"
    compile "com.android.support:appcompat-v7:28.0.0"
    compile "com.android.support:support-core-utils:27.0.2"
    compile (project(':react-native-device-info')) {
        exclude group: 'com.google.android.gms'
    }
    compile project(':react-native-config')
    compile fileTree(dir: "libs", include: ["*.jar"])
    compile (project(':react-native-network-info')) {
        exclude group: 'com.google.android.gms'
    }
    compile 'com.google.android.gms:play-services-auth:12.0.1' // should be at least 9.0.0
    compile(project(":react-native-google-signin")){
        exclude group: "com.google.android.gms" // very important
    }
    compile 'com.android.support:multidex:1.0.1'
    compile 'com.google.android.gms:play-services:12.0.1' 
    compile ("com.google.android.gms:play-services-base:12.0.1") {
        force = true;
    }
    compile ("com.google.android.gms:play-services-maps:12.0.1") {
        force = true;
    }
    compile ("com.google.android.gms:play-services-gcm:12.0.1") {
        force = true;
    }
    compile ("com.google.android.gms:play-services-location:12.0.1") {
        force = true;
    }
    compile 'com.brightcove.player:exoplayer:4.+'
}

// 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 plugin: 'com.google.gms.google-services'

// [Added by react-native-background-geolocation] Purge debug sounds from release build.
def purgeBackgroundGeolocationDebugResources(applicationVariants) {
    if ((rootProject.ext.has("removeBackgroundGeolocationDebugSoundsInRelease")) && (rootProject.ext.removeBackgroundGeolocationDebugSoundsInRelease == false)) return
    applicationVariants.all { variant ->
        if (variant.buildType.name == "release") {
            println("[react-native-background-geolocation] Purging debug resources in release build")
            variant.mergeResources.doLast {
                delete(fileTree(dir: variant.mergeResources.outputDir, includes: ["raw_tslocationmanager*"]))
            }
        }
    }
}
christocracy commented 5 years ago

What are you doing with project.ext.react? You're not supposed to mess with that. Look what the android/build.gradle look like in a freshly built react-native init foo

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    ext {   // <--------- HERE IS WHERE ext vars go!
        buildToolsVersion = "28.0.3"
        minSdkVersion = 16
        compileSdkVersion = 28
        targetSdkVersion = 28
        supportLibVersion = "28.0.0"
    }
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.3.1'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

If you don't have that ext block in android/build.gradle, add it.

unlucio commented 5 years ago

What are you doing with project.ext.react? You're not supposed to mess with that.

I've no idea, as said I inherited the project and that's how I found it

Look what the android/build.gradle look like in a freshly built react-native init foo If you don't have that ext block in android/build.gradle, add it.

and that's where I put it, only difference I can spot is: my ext clausole is in a different order: would that matter?

buildscript {
    repositories {
        jcenter()
        google()
        mavenCentral()
    }
    dependencies {
        // classpath 'com.android.tools.build:gradle:2.3.3'
        classpath 'com.android.tools.build:gradle:3.1.4'
        classpath 'com.google.gms:google-services:3.1.1'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
    ext {
        googlePlayServicesLocationVersion = "16.0.0"
    }
}
christocracy commented 5 years ago

No it doesn't matter and add all the other variables in there *and implement them.

ext {
+        buildToolsVersion = "28.0.3"
+        minSdkVersion = 16
+        compileSdkVersion = 28
+        targetSdkVersion = 28
+        supportLibVersion = "28.0.0"
        googlePlayServicesLocationVersion = "16.0.0"
    }

Create your own Hello World with react-native init foo and observe how a default RN app uses the ext vars. Do the same

.
.
.
android {
+    compileSdkVersion rootProject.ext.compileSdkVersion

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    defaultConfig {
        applicationId "com.foo3"
+        minSdkVersion rootProject.ext.minSdkVersion
+        targetSdkVersion rootProject.ext.targetSdkVersion
        versionCode 1
        versionName "1.0"
    }
    .
    .
    .
}

dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar"])
+    implementation "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}"
    implementation "com.facebook.react:react-native:+"  // From node_modules
}

Your next task is to get rid of all these unnecessary exclude group, eg:

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

And all of this stuff:

compile 'com.google.android.gms:play-services:12.0.1' 
    compile ("com.google.android.gms:play-services-base:12.0.1") {
        force = true;
    }
    compile ("com.google.android.gms:play-services-maps:12.0.1") {
        force = true;
    }
    compile ("com.google.android.gms:play-services-gcm:12.0.1") {
        force = true;
    }
    compile ("com.google.android.gms:play-services-location:12.0.1") {
        force = true;
    }