10

I'm looking at creating a multi-tenancy app using Firebase and Firestore. The number of tenants will be low (something like 6 initially), and it won't be a thing where end users will be creating their own instances on the app, it will be tightly controlled by admins.

My ideal situation is to have just a single app that I can attach multiple domains to, and route requests to specific databases to fulfill them.

There are a few concerns I have:

I have read in documentation that I can create multiple databases per app, but don't see the options in my admin panel, so I'm not sure if the documentation is incorrect at present (or if it's referring to Realtime DB).

I won't want users who register to be registered to all tenants, and given the way that Firebase auth seems to work, I don't see any way that I can specify which domain the user is registering to. I had the thought to manage that in a collection that tracks which domains the user is a part of, and fake it to look like it's keeping the users siloed, but if a user registered in "two" tenants, and wanted to change their login credentials, that would change them across the network, and might be confusing.

So it sounds like that won't work as cleanly as I'd like, which would point me to option 2:

Have one frontend app, which has references to all firebase apps it can connect to, and contact the backends of separate apps to maintain a separation of data and user auth. This would solve the siloed user problem, but then I'd be maintaining several different apps on the backend, and the whole point of making the new version of this product is to get away from having to maintain multiple, similar but slightly different codebases. A solution to that issue would be to deploy from the same code repo to different apps on firebase: Would the CLI allow me to select my deploy target every time?

I suppose option 3 is to just have a headless React app contacting a node server or something, but then I'd lose all the cool Firebase goodness, and I'm really digging Firebase.

Is this a solvable problem? Or am I trying to jam a square peg into a round hole?

Thanks!

Brian Hogg
  • 161
  • 2
  • 8

2 Answers2

5

My team recently addressed a similar situation where we needed to deploy a single Angular app across multiple tenants with Firebase.

The solution we came up with was very similar to your second option:

  1. Create separate Firebase projects on the Firebase console, one for each of the tenants you plan to support.
  2. After installing the CLI and logging in under the account that has access to each of the projects you just created, add a .firebaserc in your root directory to alias each of the newly created projects. This will look something like:
{
  "projects": {
    "dev": "my-dev-project-id",
    "tenant1": "my-tenant1-project-id",
    "tenant2": "my-tenant2-project-id"
  }
}
  1. You can now locally serve your code connecting your dev firebase project via: firebase serve -P dev and deploy a specific project via: firebase serve -P dev. By default, this will deploy your project to firebase hosting and deploy any associated cloud functions you made, but you can easily customize this behavior.
  2. To deploy all projects at once, set up a simple ./deploy-all.sh script to iterate over the projects and substitute each alias. You can also customize this to run linting/instillation etc. prior to deploying each project.
  3. Firebase hosting will automatically host each domain at your-app.firebaseapp.com and your-app.web.app. You can also customize the subdomains that each project maps to.

Caveats: The above approach relies on tenant URLs to map a project database to a user's information. On mobile, this approach becomes slightly more complicated. We have users enter a key on mobile that maps to a firebase configuration dynamically, but there may be better ways to go about this.

Luke
  • 53
  • 1
  • 5
  • keep in mind with that approach that there is a (variable) limit on how many projects you can create https://stackoverflow.com/questions/41485736/firebase-maximum-projects-and-apps – Rich Steinmetz Feb 20 '20 at 14:41
  • Apparently that 5-10 project quota is increased "substantially" (w.e that means) with the Blaze plan. Also keep in mind, Firebase functions are going bye bye Feb 2020 for free plan. – user1710344 Dec 09 '20 at 01:09
2

I realize this question is a little old at this point, but I'm also investigating this same question. I'm also only looking at a handful of tenants to start with.

I was looking into the Google Identity Platform, which supports multi-tentant auth and has native support with Firebase, from what I understand. The Firebase SDK supports selecting a tenant, and you can set up security rules to lock down various pieces of your database based on the user's tenant ID.

https://cloud.google.com/identity-platform/docs/multi-tenancy-quickstart

I think the key is your Firestore structure, so you'd have a top-level collection for each tenant, plus perhaps anything you'd like to be shared.

{
    shared: {},
    tenant1: {
        users: {},
        settings: {},
        data: {},
    },
    tenant2: {
        users: {},
        settings: {},
        data: {},
    },
    // tenant3, 4, 5, etc
}

Firebase SDK example from their docs for switching tenants within your app. There is also an example of having multiple app references in with different tenants assigned to each, if you look through that link.

// One Auth instance
// Switch to tenant1
firebase.auth().tenantId = 'tenant1';
// Switch to tenant2
firebase.auth().tenantId = 'tenant2';
// Switch back to project level IdPs
firebase.auth().tenantId = null;

This question here also talks about using the tenant in your Firestore security rules with the request.auth.token.firebase.tenant value:

https://stackoverflow.com/a/65708678/8417852

J. Sheets
  • 237
  • 2
  • 9