Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Firebase in a multi-module project

I have a multi-module multi-flavor android project, the modules are as follows:

  1. core module, which is an android library that holds common stuff, including library dependencies.
  2. authentication module, which is as the name suggests, a module that contains a bunch of UI activities and is responsible for authenticating users. It's also the module that has the launcher activity.
  3. user module, which is another android library module. It is responsible for handling user profile UI, user data, along with Firebase database. But it also has to deal with Firebase authentication to get the Uid as it's used as key in the database.
  4. Other modules that are irrelevant right now

The module core does nothing with respect to Firebase, except just include it as a dependency for other modules. So I have this in my project build.gradle:

dependencies {
    classpath 'com.android.tools.build:gradle:3.2.0'
    classpath 'com.google.gms:google-services:4.1.0'
}

and I also have this in my core build.gradle:

apply plugin: 'com.android.library'
apply plugin: 'com.google.gms.google-services'

android {
    compileSdkVersion 28
    defaultConfig {
        minSdkVersion 19
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        otherstuff
    }
    otherStuff
}

dependencies {
    otherStuff
    api 'com.google.android.gms:play-services-base:16.1.0'
    api 'com.google.firebase:firebase-core:16.0.6'
    api 'com.google.firebase:firebase-auth:16.1.0'
    api 'com.google.firebase:firebase-database:16.0.6'
    api 'com.google.firebase:firebase-storage:16.0.5'
    api 'com.hbb20:ccp:2.2.3'
    api 'com.google.android.libraries.places:places:1.0.0'
}

The user module does nothing except import the core library, and use authentication right away. So I have the following in my user build.gradle:

dependencies {
    otherStuff
    implementation project(':core')
}

and then I proceed to use it in my classes like so:

FirebaseAuth auth = FirebaseAuth.getInstance();

boolean isLoggedIn()
{
    assert(auth != null);
    return (auth.getCurrentUser() != null);
}

void uploadUserImpl()
{
    assert(isLoggedIn());
    db.getReference("users").child(auth.getCurrentUser().getUid()).setValue(this);
}

etc

The authentication module is the one that defines the app name, the launcher activity, etc. So, in my mind at least, it's also the one that should have the google-services.json file. So it has it under the authentication folder.

It includes both core and user libraries, so in my authentication build.gradle I have the following:

dependencies {
    otherStuff
    implementation project(':core')
    implementation project(':user')
}

It also proceeds to use Firebase authentication for logging in and signing up users.

Now with the problem:

trying to build the project, I get the following error:

File google-services.json is missing. The Google Services Plugin cannot function without it. 
 Searched Location: 
/work/mewais/CompanyName/ProjectName/core/src/FlavorName/debug/google-services.json
/work/mewais/CompanyName/ProjectName/core/google-services.json

and if I try to copy the google-services.json under core too, I get the following error:

No matching client found for package name 'com.companyname.projectname.core'

the google-services.json file has the app name defined inside it as:

"package_name": "com.companyname.projectname.appname"

which obviously expects the app name and not core.

So how to include Firebase in this setting? I want to keep the firebase dependencies defined inside core because multiple modules will use it. At the same time, authentication is the one that actually defines the appname and is also the one that has the launcher activity in which I start to use Firebase. I also expect user and any other modules to be able to use Firebase after that. It doesn't make sense to me to register all modules with Firebase (not even sure if it's possible since Firebase expects an app not a library?!). So is there anyway to fix this issue?

like image 844
mewais Avatar asked Feb 01 '19 05:02

mewais


People also ask

Can a Firebase project have multiple apps?

However, when you want to access multiple projects from a single application, you'll need a distinct Firebase application object to reference each one individually. It's up to you to initialize these other instances.

Can Firebase handle million users?

Queries with limited sorting and filtering functionality can be performed with the firebase database. Cloud firestore assures automatic scaling and can handle 1 million concurrent connections and 10,000 writes/second.

How many projects can I have on Firebase?

A Firebase project is a container for Firebase Apps across Apple, Android, and web. Firebase restricts the total number of Firebase Apps within a Firebase project to 30.

Can we use Firebase in frontend?

Frontend Developers can use Firebase to store and retrieve data to and from a NoSQL database called Firestore, as well as to authenticate their app's users with the Firebase Auth service.


1 Answers

I managed to wrap firebase dependencies into a library module without polluting the main module. Here is what I did:

google-play-services plugin requires the module that includes it to have applicationId and its JSON file(or it won't compile).

If you're sure you don't use special functions that google-play-services plugin provides, you can delete them.

https://developers.google.com/android/guides/google-services-plugin

Then you can follow this article's instructions:

https://medium.com/@samstern_58566/how-to-use-firebase-on-android-without-the-google-services-plugin-93ecc7dc6c4

Update: Another Link

https://firebase.google.com/docs/projects/multiprojects#support_multiple_environments_in_your_android_application

Because this provider is just reading resources with known names, another option is to add the string resources directly to your app instead of using the Google Services gradle plugin.

like image 74
Dewey Reed Avatar answered Oct 23 '22 01:10

Dewey Reed