Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implement Firebase inside of a Library

I want to implement Friebase notifications system inside a library that I want to use as SDK in many apps.

Firebase is asking now for an App ID, but I'm implementing it inside a library thus no App Id.

How could I achieve my goal to be able to send notifications to my apps that use my library ?

Thanks in advance.

like image 306
Aysennoussi Avatar asked Jul 26 '16 17:07

Aysennoussi


People also ask

Is Firebase a third party library?

Third-party library integrationsFirebase offers a number of integrations with open-source libraries in addition to the mobile/web SDKs and server client libraries, see Library and framework integrations.

How do I add Firebase to my website?

To add Firebase to your web service, copy your Firebase project's custom code snippet, JavaScript and CSS files into your web service: Go to the Firebase console and select your project. From the project overview page, under the text Get started by adding Firebase to your app, select web.


2 Answers

Yes you can actually do this, on your library build.gradle put this inside the defaultConfig field

buildConfigField("String", "FIREBASE_APP_KEY", "\"${firebaseAppKey}\"") 

Then inside your project's gradle.properties

firebaseAppKey = <yourFirebaseAppSecret>;

For each project/app you must define this variable on your gradle.properties.

You'll have to create a firebase app for each project, but your library can now have the Firebase SDK.

When you want to access this environment variable value use BuildConfig.FIREBASE_APP_KEY (e.g. instantiate firebase).

like image 198
Joaquim Ley Avatar answered Sep 21 '22 17:09

Joaquim Ley


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 Services 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.

like image 35
Sakiboy Avatar answered Sep 21 '22 17:09

Sakiboy