Scaling your Realtime Database just got a lot easier. We're excited to announce multi-database support in your Firebase Projects!
The Realtime Database is capable of handling a lot of traffic, however it does have its limitations. Scaling past these limits requires "sharding" your data across multiple databases to handle the load. Traditionally, you would need to create another project to get another database. If you need to scale again, you would need to repeat this process.
While this is possible, it's not exactly easy. It's not fun to manage data across multiple projects and authentication is different per project. This generally requires you use Custom Authentication in Firebase Auth, which can be a lot more work. We're happy to say that multi-database solves these problems.
Multi-database allows you to create multiple database instances in a single project. This eliminates managing data across multiple projects. To get started you need to be in the Blaze plan. In the data viewer you can click the triple dot icon to create new database instances:
To access data from a secondary instance you use an absolute URL when creating a database instance.
const app = firebase.initializeApp({ // use your main config databaseUrl: "https://multi-db.firebaseio.com/" }); // This is the default DB. const db1 = app.database(); // Reference the second DB instance. // Keep in mind that you need to upgrade to the latest release before this will work! const db2 = app.database("https://multi-db501c7.firebaseio.com/");
Since these databases are in the same project they share the same Authentication session. Which means no custom server is required.
Important note on SDK versions: Keep in mind that if you have an existing app as of the time of this blog posting, you'll need to upgrade to the latest SDK versions before this will work. (For node admin, you need at least 5.5.0, and inside Cloud Functions you will need at least 0.7.3).
How you shard your database depends on your application. However, there are many useful techniques.
The Master Shard
You can create a "master shard" that contains the mappings to where the data is located in other database shards. This allows you to only request heavier sets of data when needed.
{ "chatrooms": { "general": "room-db-general", "randomchat": "room-db-randomchat", "sweetgifs": "room-db-sweetgifs" } }
Bucketing
You can bucket data per database. This means you can have a users database, a messages database, and a receipts database.
Per customer
If you're developing a multi-tenant service another option is to create a database per customer. This approach ensures that your customers' databases are isolated, in case of load or an outage, it doesn't affect all of your customers.
Each database instance has its own set of security rules. Sharded databases can handle different structures which means you can apply different rules based on that database's purpose. You can manage and test each database's rule set in the console. It's important to note that databases are completely independent. This means you cannot access another database's data in rules evaluation.
We're also excited to announce that Cloud Functions for Firebase supports multi-database as well! You can specify which database you wish to trigger events from:
const functions = require('firebase-functions'); const firebase = require('firebase-admin'); firebase.initializeApp(functions.config().firebase); exports.copymsg = functions.database.instance('room-db-randomchat').ref('/messages').onWrite(event => { const { data } = event; const notificationDb = firebase.database(<your-full-db-url>); return notificationDb.ref(`notifications/${data.key}`).set(data.val()); });
Note that the absolute URL is not required for functions. If no database instance is provided Cloud Functions uses the default database.
const functions = require('firebase-functions'); const firebase = require('firebase-admin'); firebase.initializeApp(functions.config().firebase); // triggers off your default database exports.sanitize = functions.database.ref('/messages').onWrite(event => { // sanitize message here });
Multi-database is an easier way to get to scale with the Realtime Database. We hope you like it, and if you want to learn more check out our documentation. We also have an official support channel, a Slack channel, and we monitor our StackOverflow tags. Don't hesitate to reach out to us!