Skip to content
This repository has been archived by the owner on May 21, 2019. It is now read-only.

Android build problems

Christian Brevik edited this page Sep 13, 2018 · 1 revision

Intro

A lot of people are encountering Android build-problems where Play Services-versions which React Native-modules depend on, do not match. This post is an attempt to explain the solution.

The problem

As an example, the react-native-firebase@4.3.8 module depends on firebase-core:16.0.1 and play-services-base:15.0.1 (and a lot of others depending on how you use their module). While react-native-google-analytics-bridge@6.1.0 depends on play-services-analytics:+ and play-services-tagmanager-v4-impl:+, where + just mean "the latest".

If you try to build the React Native Android-app, with react-native-firebase and react-native-google-analytics-bridge set at these versions, you will get the following error (as in #280):

FAILURE: Build failed with an exception.

* What went wrong:
Failed to capture snapshot of input files for task ':app:preDebugBuild' property 'compileManifests' during up-to-date check.
> The library com.google.android.gms:play-services-measurement-base is being requested by various other libraries at [[16.0.2,16.0.2], [16.0.0,16.0.0]], but resolves to 16.0.2. Disable the plugin and check your dependencies tree using ./gradlew :app:dependencies.

The problem here is that different versions of underlying dependencies are being requested between these dependencies (firebase-core, play-services-analytics, etc). A good place to check what these underlying dependencies are is at https://mvnrepository.com.

For example, the site says that firebase-core:16.0.1 has firebase-analytics:16.0.1 and firebase-measurement-connector-impl:16.0.1 as dependencies (see Compile Dependencies further down on that page). These in turn depend on play-services-measurement-base:16.0.0, which is the dependency being complained about.

Now play-services-analytics:16.0.3 (which is the latest, remember +) depends on play-services-measurement-base:16.0.2, which is where the trouble starts (16.0.0 vs 16.0.2).

The easy solution

So the solution here is to pin the react-native-google-analytics-bridge dependencies to a version which will match with react-native-firebase. So if we look at play-services-analytics' versions, we see that play-services-analytics:16.0.1 depends on play-services-measurement-base:16.0.0

Pinning the version can be done in many ways. This module has implemented the same ability as a lot of other RN modules in the community, by allowing the Play Services-version being set through googlePlayServicesVersion in the gradle script. This can be done as such in <your-RN-app>/android/build.gradle:

buildscript {
    ext {
        googlePlayServicesVersion = "16.0.1"
        // ... rest of ext properties
    }
	// ... rest of gradle buildscript
}

The above will set play-services-analytics and play-services-tagmanager-v4-impl at 16.0.1. And should fix the problem.

This will also do the same for other modules implementing googlePlayServicesVersion, like react-native-device-info.

The advanced solution

Sometimes, Play Services will still mismatch even if you use googlePlayServicesVersion. For example, as you see react-native-device-info depends upon play-services-gcm, which has no 16.0.1 version (at the time of this writing).

In this case, instead of using googlePlayServicesVersion, you can also force dependencies resolution by adding a resolution strategy in your <your-RN-app>/android/build.gradle:

allprojects {
    repositories {
        google()
		mavenLocal()
        // .. etc
        configurations.all {
            resolutionStrategy {
                // react-native-google-analytics-bridge
                force "com.google.android.gms:play-services-analytics:16.0.1"
                force "com.google.android.gms:play-services-tagmanager-v4-impl:16.0.1"
				// react-native-device-info
                force "com.google.android.gms:play-services-gcm:15.0.0"
            }
        }
    }
}