These are all kinda hacky or too much work, here’s a nice n simple example (ironic though, cause it’s a long post -- but worth it).
It is possible to use FireBase
code in your library project, of course the consuming application will need to register the app and get the app ID / google-services.json
file.
But your library doesn’t, and shouldn’t care about about that, it’s the consuming applications job to do that, not your library.
Here’s a brief example using the firebase-messaging
module inside of a library project.
YourLibrary module’s build.gradle:
// Other typical library set up
apply plugin: 'com.android.library'
android {
compileSdkVersion 27
defaultConfig {
minSdkVersion 16
targetSdkVersion 27
versionCode 1
versionName '1.0'
// Don’t for get your library’s proguard file!
consumerProguardFiles 'proguard-rules.pro'
}
}
ext {
currentFirebaseVersion = "11.8.0"
}
dependencies {
/*
Here we depend on the firebase messaging dependency (via compileOnly),
allowing us to use the FireBase API within our library module.
I exclude that org.json module because it may cause build warnings, this
step isn’t totally necessary.
NOTE: You should use `compileOnly` here so the dependency is
not added to the build output You will be allowed to use the
dependency in your library. If the consuming app wants to use firebase
they’ll need to depend on it (using `implementation`).
*/
compileOnly("com.google.firebase:firebase-messaging:$currentFirebaseVersion") {
exclude group: 'org.json', module: 'json'
}
}
// Other typical library set up. But nothing else relating Firebase.
This is all you need to do in your library project. DON’T apply the gms plug in here, and don’t add the google-services classpath to the libraries build.gradle
.
Now here’s how you set up your consuming app:
MyClientApp’s top-level build.gradle:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google() // You know the drill...
}
// Any other set up you might have...
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
/*
Here in your client app’s top-level build.gradle you add the
google-services to the app’s classpath.
*/
classpath 'com.google.gms:google-services:3.2.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
// Other basic stuff...
allprojects {
apply plugin: 'maven'
apply plugin: 'maven-publish'
repositories {
jcenter()
google()
}
}
Now we need to set up the consuming applications module build.gradle
, it’s simple. We pretty much just need to apply the plug-in, and depend on the library module that we create that has all the FireBase
code in it.
MyClientApp’s module level build.gradle:
buildscript {
repositories {
google()
mavenLocal()
}
}
apply plugin: 'com.android.application'
android {
compileSdkVersion 27
defaultConfig {
applicationId "com.your.application.that.can.use.firebase"
minSdkVersion 16
targetSdkVersion 27
versionCode 1
versionName '1.0'
}
//other typical set up
}
ext {
currentFirebaseVersion = "11.8.0"
}
dependencies {
implementation('com.your.library:YourLibrary:1.0@aar') {
transitive = true
// Use the consuming application's FireBase module, so exclude it
// from the dependency. (not totally necessary if you use compileOnly
// when declaring the dependency in the library project).
exclude group: 'com.google.firebase'
// Exclude the "plain java" json module to fix build warnings.
exclude group: 'org.json', module: 'json'
}
implementation("com.google.firebase:firebase-messaging:$currentFirebaseVersion") {
// Exclude the "plain java" json module to fix build warnings.
exclude group: 'org.json', module: 'json'
}
}
// Needs to be at the bottom of file.
apply plugin: 'com.google.gms.google-services'
Some things to note:
- Must apply google-services plugin at the bottom (only in the client module
build.gradle
).
- Depend on the library module that has the
FireBase
code in it, but exclude it’s version of the FireBase
module, in favor of your own dependency version.
- App depends on it's own
FireBase
version.
classpath 'com.google.gms:google-services:3.1.1’
only goes in the client app’s top level build.gradle
.
- Of course you will need to register the client app and put the
google-services.json
in your client app’s project.
- Define the necessary
Firebase
Service
s in your app’s manifest (or use manifest merger and merge them in from your library project)
- Add the
google_play_services_version
meta-data tag to your client app’s Manifest.
- The library can/should use
compileOnly
when declaring the FireBase
dependency.
Now you’ll be able to use FireBase
code in your app that you defined in your library that uses FireBase
. Or you could let your library module do all the FireBase
work!
Of course this is typically used for internal libraries, as frameworks like Firebase
weren’t designed to be implemented in library modules, but sometimes you need to, so this is a simple non-hacky/sane solution to the issue. It can be used on projects that are distributed through maven -- my library uses this, and it’s never caused any issues.
Update:
You should use compileOnly
when declaring the library module's Firebase
dependency. By doing so the dependency will not be added to the build output. But you will be allowed to use the dependency in your library. If the consuming app wants to use firebase they’ll need to depend on it manually (using implementation
). This will help cut down on unneeded dependencies/bloat in applications and the “right” way to declare a dependency like this. Note: You may need to perform runtime checks to make sure the library is available before using it’s code in your module.