Robase - A Luau wrapper for Firebase Real-time Database

Robase - A Firebase Real-time Database Wrapper

Github Release API Docs Github Repo Roblox Model
v2.1.0-beta.rc

What is RobaseService?

Robase is a RESTful API wrapper for Firebase Realtime Database - written in untyped Luau - for Roblox Developers seeking an external database service with a simple to use wrapper.

As mentioned, Robase seeks to be simple to use, but this is one of two core aims of this project. The second aim is to be an easy replacement to DataStoreService. You can find useful code to help with replacing old DataStore code and transferring data here.


Why RobaseService?

RobaseService aims to provide a reliable and safe method of saving and loading data, no matter how big or small. But what does it offer that DataStoreService doesnā€™t?

  • You are no longer limited to 4MB of data per key, your database can hold 1GB of storage and you have complete control over how everything is stored.

  • You can access any key within the real-time database, simply use ā€œ/ā€ to separate the keys. With DataStores you only have access to one point, making querying difficult and ensuring all data exists a slog with sanity checks.

  • Robase is open-sourced, this means that its source code is available to everyone and can be looked at and researched easily especially with the source documentation! This will make extending and wrapping RobaseService simpler and creating an extension similar to DataStore2 by @Kampfkarren or a manager like ProfileService by @loleris.

  • The methods are guaranteed to be race condition free, Robase uses Promises by @evaera to ensure race safety. Every async function will yield until a value is retrieved. There are also two methods which return promises, these are Robase:Set() and Robase:Get() and are documented here

  • You can update keys externally, there is no need to go into game to update a DataStore. Simply go to the Firebase Console and access your database and modify away! Entering a live game isnā€™t practical most of the time, this makes the process easier and more accessible - you can even do it on your phone!

For more in-depth explanation of the above points you can go to the limitations section of the API Docs.


Firebase Setup

note: In order to keep this article concise, this section will be hidden by default. Click the link above to navigate to the docs page covering this section.

Getting Started

Before you can use RobaseService you will first need to create a new Firebase project, this can be done from the Firebase Console. Once you have followed the instructions and started a new project, you will need to open the side-bar menu and go to your ā€œRealtime Databaseā€ and then ā€œCreate Databaseā€, you will then have a pop-up appear configuring your database and the security rules for it.

Finding your Database Url

You can find your Database URL by going to the Firebase Console and opening up your Real-time Database. You should be met with a page that looks like this:

In the green box is your URL, it should be formatted like so:

{database-name}-default-rtdb-{server-location}.firebasedatabase.app/

NOTE: This is the baseUrl parameter of RobaseService.new().

Finding your Database Secret

Your database secret will be serving as your authentication token for your requests, this can be created or found by following the image and step-by-step instructions below.

When you create your database a database secret should be generated automatically, but you can create more.

WARNING: You must have created your database first, if you have just created your project you will not be able to create a database secret. Read the opening paragraph of this page for help with creating your database.

  1. Begin by navigating to your Firebase Console
  2. Click on the gear icon next to ā€˜Project Overviewā€™
  3. Click ā€˜Service Accountsā€™ in the tabs that appear
  4. Click ā€˜Database Secretsā€™
    4.a) If a secret does not this exist then ā€œaddā€ (create) a new one
  5. Hover over the secret and reveal it, then copy it and save it somewhere safe.

NOTE: The value of your database secret is the token parameter of RobaseService.new().


Robase Setup

RobaseService is made to be a replication of DataStoreService so that setup and transferring data are simple to do.

Example

Code that once looked like this:

local DataStoreService = game:GetService("DataStoreService")
local ExampleDataStore = DataStoreService:GetDataStore("Example")

local ExampleData = ExampleDataStore:GetAsync("123456789")

Will now look like this:

local RobaseServiceModule = require(path.to.robase)
local RobaseService = RobaseServiceModule.new("URL", "AUTH")
local ExampleRobase = RobaseService:GetRobase("Example")

local Success, Result = ExampleRobase:GetAsync("123456789")

Every Async method call to a Robase will return a Success and a Result, check the API Reference for more detailed information.


Usage Guide

An in-depth usage guide can be found at the link above, it will not be covered in this post as it falls out of scope of this category.


API Reference

As the API Reference page is extensive, it will be omitted in favour of the docs page that covers it. If you wish to find out more about the methods and internals of RobaseService, use the link above.


Closing

For issue reporting see here for information on the different methods.

Thank you for reading through this article. Any and all feedback is appreciated, if you like this opensource software donā€™t forget to like the post and if it is something you may consider using star the GitHub!

60 Likes

How could I modify this to use Firestore rather than the Real-time Database?

1 Like

You couldnā€™t, Iā€™m afraid this is exclusively a realtime database wrapper.

I have looked into Firestore and the authentication is a little more involved and AFAIK the public api is unreliable and Iā€™m thinking its do with how often its being called from other clients.

It is something that I am looking into, however.

For now I plan to add extensions/features to Robase to make it a little more powerful (such as querying & transactions).

v2.1.0-beta is now available from Github, release & documentation have yet to be updated as its quite a large addition.

2.1.0-beta brings querying support to Robase, the equivalent Firebase documentation is found under ā€œordered dataā€ and ā€œfiltered dataā€ sections of the REST API.

Documentation & a release are currently in the works and will be out in the coming weeks.

This is really cool not gonna lie, I might use it in the future.

1 Like

RobaseService 2.1.0-beta-rc

(Official release)

Changelog

  • Added support for the following query parameters: orderBy, shallow, limitToFirst, limitToLast, startAt, endAt, and equalTo.
  • Documentation has been added for querying your database, see here for the API Reference.
  • Gave the API Reference page a makeover and changed the look of the ā€œcall-outsā€ (aka ā€œcautionā€, ā€œtipā€, etc.) to fit better with the website theme.
  • Latest Github Release now includes a .rbxm file for you to drop into your studio session. Documentation for this will be added soon.
  • Updated the Roblox Model to current version.
  • You no longer have to wrap your Robase method calls with a pcall this is done behind the scenes (see: HttpWrapper.lua on Github).

Further changes are documented on the documentation site.

This update is backwards compatible so no need to worry about your code breaking.

Iā€™ve been using firebase for quite a long time now, connecting it to both roblox and my own discord bot. Iā€™ve found that after you have used up the spark plan, it disables the connection between the game and the server. This comment is intended as a heads up for the people who wouldnā€™t want to purchase the blaze plan on firebase. I do recommend the datastore over any of the rest.

1 Like

This is super underrated. Thanks for your hard work!

1 Like

Thank you everyone for the support so far! Currently working on a few exciting things, with additional details that are in-effect!

  • The Material MkDocs documentation site is going to be replaced, I am currently working on using Moonwave - a documentation generator for Lua using Docusaurus - to build a documentation page. Fear not, a lot of the content that is currently available will still be available. I will be revising a lot of the content and hopefully making everything easier to read.

  • RobaseService is now available on the Wally package manager! Just put RobaseSevrice = "shanebutt/robase-service@2.2.1" under server-dependencies in your wally.toml file. This change is already effective and will give you the latest version of RobaseService.

  • The addition of pcall into HttpWrapper.lua (robaseā€™s lua promise http wrapper) has been removed: No method needs to be wrapped by a pcall when used. This means: local ok, result = pcall(Robase.GetAsync, "Key") is not necessary, it never was! However, speaking of this file, error handling will ~hopefully~ now be more robust and graceful. Oh, and it has been renamed to promiseHttpRequest.lua.

  • Heavily considering moving the Github Repo under my name away from my studio, this isnā€™t confirmed or final yet.

  • Considering changing the querying methods into static functions (from Robase:orderBy(...) to Robase.orderBy(yourRobase, ...)). This just seems and feels a lot more authentic, it still requires you to have a defined Robase, but this way you are able to create ā€œcopiesā€ with query parameters and it will feel more natural, hopefully. local orderedRobase = Robase.orderBy(myRobase, "$key").equalTo("31210430") vs local orderedRobase = myRobase:orderBy("$key"):equalTo("31210430")


Current Versions
Wally: 2.2.1
Github: 2.1.0
Roblox: 2.1.0

All of these will be updated to v2.3 when the above changes and considerations are made.

1 Like

This isnā€™t really relevant to Robase itself, but I figure I need some help. Iā€™m trying to kick people in a game if they are in the player array.

Code:

local RobaseServiceModule = require(script.Parent.RobaseService)
local RobaseService = RobaseServiceModule.new(removed_for_devforum)
local Robase = RobaseService:GetRobase()
local Success, playertable = Robase:GetAsync("player")
print(playertable)


local HTTPService = game:GetService("HttpService")
game:GetService("Players").PlayerAdded:Connect(function(player)
	local tablee = HTTPService:JSONEncode(playertable)
	if table.find(tablee, player) then 
		player:Kick()
	end
end)

Firebase Structure:

Thank you for any help, and thanks for making this module!

1 Like

You donā€™t need to use the Json encode/decode methods on your data, Robase does this for you. That seems to be the issue here.

Youā€™re also encoding into json when you load the data (it would be decode from) but neither is necessary.

1 Like

Look forward to using this service sometime, though can we create a new ā€œRobaseā€ using only a URL and no auth/token (Secret)? Iā€™d like to set my rules to allow anyone to read data inside my database and only be able to write to it with the secret/auth/token. Thanks for all your work.

1 Like

Hi, thatā€™s a great question! In v3 of RobaseService I aim to overhaul authentication and apply better rate limiting and error handling for those.

Ideally, RobaseService could perhaps check the rules of the database in some way or another, and handle failed requests appropriately.

In the future, I suspect the API could like either of these two ways:

local RobaseService = require(path.to.robase)
local Database = RobaseService:Connect("URL"):expect()
Database.Authenticate("TOKEN"):andThen(print)

local Robase = Database:GetRobase("name", "scope")
--...

local Database = RobaseService:Connect("URL", "TOKEN"):expect()
print(Database.Authenticated)

local Robase = Database:GetRobase("name", "scope")

Long story short; authentication will be improved and handled way better. There will also be other improvements and changes in v3.0 which can be found in the github issues page

What do you think someone should know about before using this in their game Scripting-wise? Iā€™ve been looking into firebase for my game and I find this very interesting.

1 Like

From what Iā€™ve gathered over the last two years with discussions amongst some notable developers thereā€™s one notable concern: Firebase isnā€™t all that scalable, itā€™ll work great for smaller games, but once you scale up its usually best to find other solutions.

Iā€™ve personally not had an issue using Firebase with the small games Iā€™ve helped produce and script. I would love to know peopleā€™s experiences using it and the scale at which their data.

Other than that, Iā€™ll list some things to take care of (they are noted in the documentation too!):

  • NEVER store your database secrets in plain text in your code!!
  • Keys do not need to be prefixed or suffixed with ā€œ/ā€ theyā€™ll be stripped away and transformed into the URL anyway.
  • Much like DataStores be mindful or how youā€™re saving and loading data, a cache system that uses Robase is optimal.
  • The Query methods for Robase are still experimental and not fully tested out. Furthermore the results are unsorted but will be filtered however specified.

Canā€™t think of more right now, be sure to read the documentation, and join the server to discuss it more!

MySQL/MongoDB: Am I a joke to you?

But for real, no one is using more than 4 mb of data per key. Otherwise, their data base system is inefficient

The points to take away from that quote are these:

  • Firstly, you can more finely control how data is stored and also have an easier time reasoning about it.
  • Secondly, usually, games will split data across several keys (for extra storage for the player) and have backups and all this jazz that ends up being a big mess of data stores, in my opinion at least, and itā€™s far simpler having one or maybe two databases and reasoning about your data more efficiently. ā€œDamn, which data store did I put X in for players?ā€.

Though I do only slightly agree that using that much seems like a problem, sometimes thereā€™s a lot of data.

Hey are this project still running or discontinued?. I mean still got any update/bug fix ?

Still being maintained and updated, change log can be found on the docs site. Big updates to come but nothing to show or discuss just yet, future plans can be found on the Github issue page.

Hi is this better than the famous Profile Service?