How to fix provider related errors during manifests merge after dynamic-feature plugin migration

168
September 13, 2019, at 9:00 PM

My app has 3 modules: app (my base module), installed_feature (my installable feature module) and verification (feature module). After doing the migration to the new dynamic feature plugin as described in https://developer.android.com/topic/google-play-instant/feature-module-migration, and resolving various dependency issues that came up, I've arrived to a point in which I'm having the following manifest merge error only in the verification module:

Error: Attribute provider#com.google.firebase.perf.provider.FirebasePerfProvider@authorities value=(com.myapp.firebaseperfprovider) from AndroidManifest.xml:300:15-67 is also present at AndroidManifest.xml:30:13-72 value=(com.myapp.verification.firebaseperfprovider). Suggestion: add 'tools:replace="android:authorities"' to element at AndroidManifest.xml:300:5-188 to override. verification main manifest (this file), line 299

What I've tried

First, I've tried to solve it quickly by just adding tools:node="replace" to the application tag of every manifest, and it allowed me to compile and run, but it caused the app to throw IllegalStateException: Default FirebaseApp is not initialized in this process com.myapp. Make sure to call FirebaseApp.initializeApp(Context) first. at startup.

When I applied the solution suggested in the error message, adding this to the manifest

<provider
  android:name="com.google.firebase.perf.provider.FirebasePerfProvider"
  android:authorities="${applicationId}.firebaseperfprovider"
  tools:replace="android:authorities" />

then the same error came up for other providers of sdks I'm using (like Facebook, AccountKit, Crashlytics), so I ended up having 5 other blocks like that in my manifest. Also, after that, the app compiled, but in order for it to run properly, I would have to implement manual initialization for each and every one of the libraries whose provider I've replaced in this way. That's not a satisfactory solution, and it seems to me that it not address the root cause of the problem.

I think the problem may be due to something related with the name of the packages or the applicationId, but I couldn't find any clue to solve it (I've also tried changing the package name where my base module is, from com.myapp.base to com.myapp, without any effects)

This are the relevant parts of the manifests and gradle files of the 3 modules:

app module build.gradle:

apply plugin: 'com.android.application'
apply plugin: 'com.google.firebase.firebase-perf'
apply plugin: 'io.fabric'
android {
    compileSdkVersion 28
    buildToolsVersion '28.0.3'
    dynamicFeatures = [":installed_feature", ":verification"]
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        debug {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            ext.alwaysUpdateBuildId = false
        }
    }
    defaultConfig {
        applicationId "com.myapp"
        minSdkVersion 16
        targetSdkVersion 28
        versionCode rootProject.versionCode
        versionName rootProject.versionName
    }
}
dependencies {
    api 'androidx.appcompat:appcompat:1.0.2'
    api 'androidx.recyclerview:recyclerview:1.0.0'
    api 'androidx.cardview:cardview:1.0.0'
    api 'com.google.android.material:material:1.0.0'
    api 'androidx.exifinterface:exifinterface:1.0.0'
    api 'androidx.work:work-runtime:2.2.0'
    api 'com.google.android.libraries.places:places-compat:2.0.0'
    api 'com.google.android.gms:play-services-auth:17.0.0'
    api 'com.google.api-client:google-api-client-android:1.22.0'
    api 'com.google.apis:google-api-services-people:v1-rev327-1.24.1'
    api 'com.google.firebase:firebase-core:17.2.0'
    api 'com.google.firebase:firebase-auth:19.0.0'
    api 'com.google.firebase:firebase-messaging:20.0.0'
    api 'com.google.firebase:firebase-dynamic-links:19.0.0'
    api 'com.google.firebase:firebase-firestore:21.0.0'
    api 'com.google.firebase:firebase-appindexing:19.0.0'
    api 'com.google.firebase:firebase-ml-natural-language:21.0.1'
    api 'com.google.firebase:firebase-ml-natural-language-language-id-model:20.0.4'
    api 'com.google.firebase:firebase-storage:19.0.0'
    api 'com.google.firebase:firebase-database:19.0.0'
    api 'com.google.firebase:firebase-perf:19.0.0'
    api 'com.crashlytics.sdk.android:crashlytics:2.10.1'
    api 'com.android.volley:volley:1.1.1'
    api 'com.google.code.gson:gson:2.8.5'
    api 'com.facebook.android:facebook-core:5.0.3'
    api('com.facebook.android:facebook-login:5.0.3') {
        exclude group: 'com.google.zxing'
        exclude module: 'com.google.zxing'
    }
    api 'com.facebook.android:account-kit-sdk:4.39.0'
    api 'androidx.constraintlayout:constraintlayout:1.1.3'
}
apply plugin: 'com.google.gms.google-services'

app module Manifest:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:dist="http://schemas.android.com/apk/distribution"
    package="com.myapp.base">
    <dist:module dist:instant="true" />
    <application android:name="com.myapp.MyApplication"
        android:label="@string/app_label"
        android:icon="@mipmap/ic_launcher"
        android:theme="@style/AppTheme"
        android:allowBackup="false"
        android:largeHeap="true"
        tools:replace="android:label,android:allowBackup">
        ...
        <meta-data
            android:name="com.facebook.sdk.ApplicationId"
            android:value="@string/facebook_app_id" />
        <meta-data
            android:name="com.facebook.accountkit.ClientToken"
            android:value="@string/account_kit_app_id" />
        <meta-data
            android:name="com.facebook.accountkit.ApplicationName"
            android:value="MyApp" />
        <meta-data android:name="com.facebook.sdk.AutoLogAppEventsEnabled"
            android:value="true"/>
        <meta-data android:name="com.facebook.sdk.AdvertiserIDCollectionEnabled"
            android:value="true"/>
        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />
        <meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="..."/>
        <meta-data
            android:name="com.google.android.gms.ads.APPLICATION_ID"
            android:value="@string/admob_app_id"/>
    </application>
</manifest>

installed_feature buid.gradle:

apply plugin: 'com.android.dynamic-feature'
android {
    compileSdkVersion 28
    buildToolsVersion '28.0.3'
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    defaultConfig {
        versionCode rootProject.versionCode
        versionName rootProject.versionName
        minSdkVersion 16
        targetSdkVersion 28
    }
}
dependencies {
    implementation project(':app')
    implementation project(':verification')
    implementation 'com.google.android.exoplayer:exoplayer-core:2.10.4'
    implementation 'com.google.android.exoplayer:exoplayer-ui:2.10.4'
    implementation "com.google.android.gms:play-services-maps:17.0.0"
    implementation 'com.google.maps.android:android-maps-utils:0.4.5-SNAPSHOT'
}
apply plugin: 'com.google.gms.google-services'

installed_feature Manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.myapp"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:dist="http://schemas.android.com/apk/distribution">
    <dist:module dist:instant="false" dist:onDemand="false"
        dist:title="*installable*">
        <dist:fusing dist:include="true" />
    </dist:module>
    <application
        android:label="@string/app_label"
        android:allowBackup="false"
        tools:replace="android:label,android:allowBackup">
      ...
    </application>
</manifest>

verification build.gradle:

apply plugin: 'com.android.dynamic-feature'
android {
    compileSdkVersion 28
    defaultConfig {
        minSdkVersion 16
        targetSdkVersion 28
        versionCode rootProject.versionCode
        versionName rootProject.versionName
    }
}
dependencies {
    api project(':app')
}
apply plugin: 'com.google.gms.google-services'

verification Manifest:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:dist="http://schemas.android.com/apk/distribution"
    package="com.myapp.verification">
    <dist:module dist:instant="true" dist:onDemand="false"
        dist:title="*verification*">
        <dist:fusing dist:include="true" />
    </dist:module>
    <application
        android:label="@string/app_label"
        android:allowBackup="false"
        tools:replace="android:label,android:allowBackup">
        ...
    </application>
</manifest>

Top Level build.gradle:

buildscript {
    repositories {
        google()
        jcenter()
        mavenCentral()
        maven { url 'https://maven.fabric.io/public' }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.5.0'
        classpath 'com.google.gms:google-services:4.3.2'
        classpath 'com.google.firebase:perf-plugin:1.3.1'
        classpath 'io.fabric.tools:gradle:1.31.0'
    }
}
allprojects {
    repositories {
        google()
        jcenter()
        mavenCentral()
        maven { url "https://oss.sonatype.org/content/repositories/snapshots" }
        maven { url "https://jitpack.io" }
        maven { url 'https://jcenter.bintray.com' }
        maven { url "https://maven.google.com" }
    }
}
Rent Charter Buses Company
READ ALSO
Android canvas remember previous paintings on invalidate

Android canvas remember previous paintings on invalidate

When using invalidate the history of previous drawing actions are goneI want to create an animation where I draw some new pixels after a certain delay

168
How to handle FB Login revocation or expiry in Android and iOS

How to handle FB Login revocation or expiry in Android and iOS

The official Facebook Developer documentation does not mention how to handle the case for FB login access token expiry case or the case when the user revokes access to the app via FB settings

135
Cannot get a list of Item objects from Firestore

Cannot get a list of Item objects from Firestore

I have a class that looks like this:

168
The SHA1 of &ldquo;App signing certificate&rdquo; and &ldquo;Upload certificate&rdquo; each belong to two different keystores. How is this possible?

The SHA1 of “App signing certificate” and “Upload certificate” each belong to two different keystores. How is this possible?

For a couple of days, I've been trying to upload the aab of an existing app of my employerI found that we're already enrolled into App Signing

133