Getting OneSignal Working On A Multi-Module Project
Recently, upon attempting to implement OneSignal for user notifications (and following their installation instructions), a wide variety of intriguing and mysterious build errors were encountered.
The root cause of these seemed to be their gradle plugin (ironically intended to simplify the dependency process, and solve any Google Play Services issues) causing issues when attempting to be applied to a project with 10+ modules inside it. Luckily, the fix was pretty straight forward.
First, a few of the errors encountered:
com.google.android.gms:play-services-measurement-base is being requested by various other libraries
Android dependency is set to compileOnly/provided which is not supported
Error: Program type already present: com.google.android.gms.internal.measurement.zzwo
java.lang.NoClassDefFoundError: com.google.android.gms.gcm.GoogleCloudMessaging
Duplicate key com.android.build.gradle.internal.api.artifact.BuildableArtifactImpl@7c139f68
The reason behind these issues ultimately boiled down to:
- The Gradle plugin being useful in an ideal situation, but just muddying the waters if trying to resolve an issue manually.
- The library’s
build.gradle
containing a few old Google Play Services dependencies (e.g. 12.0.1), and some unusual syntax. - The OneSignal library not being designed for a project with many modules.
The solution settled on was unfortunately not at all ideal, but it did get notifications working perfectly:
- Remove all code to do with the Gradle plugin, it’s not necessary.
- Download the module as a
.zip
and import it into your project manually. - Update the Google Play Services version to the same as the rest of your project.
- Add
implementation ‘com.google.android.gms:play-services-ads:15.0.1’
to the new submodule’sbuild.gradle
, or a few files within won’t compile. - Fix a couple of files that have missing imports.
- Resync Gradle, and skip to Step 2 of the OneSignal setup docs.
- Note: If you’re using build flavours, make sure you change those in the new submodule to match your own.
Whilst the solution did work, unfortunately it’s a very hacky approach, just downloading the library and manually messing the the gradle files. Hopefully in the future the OneSignal library’s multi module support improves.