CactusBase 2 - A simple extenal database

__________________ CACTUSBASE 2 __________________


What is CactusBase

It’s an external database module which you can use to get and edit data.


Usage

Get the CactusBase 2 ModuleScript and put it in ReplicatedStorage. Then use GetDatabase(ID, SCOPE) to get a database for your game.

> IDs and GUIDs

TL;DR: DON’T CHANGE OR LEAK THE ID AND SCOPE AND USE A GUID.

Your ID is the id of the database, and is where data will be stored. Changing the ID or the SCOPE will cause you to lose all your data.

It’s recommanded that you use a GUID for your ID so that’s it’s much harder to access your database and data. As long as you don’t leak or give access to the ID and SCOPE of the database, it’s impossible for someone to get access to your data.

To get a GUID for your game you can use HttpService. Run this command in the View > Command Bar and copy paste the printed id text as your id. The harder you make it, the harder it is to crack.

print(game:GetService("HttpService"):GenerateGUID(false))

Creating a database

local CactusBase = require(game.ReplicatedStorage.CactusBase2)
local Database = CactusBase:GetDatabase("PUT_ID_HERE", "PUT_SCOPE_HERE")

Setting/Saving data

Use Database:SetAsync(key, data) to set data. The key must be a string and the data can be any value (This includes QuickLists.) but it’s best to use dictionaries for saving data.

local res, err = Database:SetAsync("player-userId",{
    Coins = 100,
    Inventory = {}
})
if not res then
   print('Data could not be saved:', err) -- Save error
end

Getting/Loading data

Use Database:GetAsync(key) to get data. The key must be a string. It will return the data that was set. (If a QuickList was Set as the data only the array table will be returned, and you’ll have to make it a QuickList again.)

local data, err = Database:GetAsync("player-userId")
if not data then
   print("Data could not be loaded or doesn't exist.:")
end

It’s as simple as that. Just add that into your script.


FAQs

FAQs

Can I port data from DataStoreService into CactusBase?

Not as of now, but if possible, you could get all the data of the users and use a script or command bar to set all the data to CactusBase 2 using SetAsync().

Can I use this with QuickList?

Yes, setting data is possible using my QuickList class. Unfortunately, the data returned from GetAsync() is a dictionary and you’ll have to re-convert the returned data into a quicklist. It’s as simple as doing _( data ). Also I don’t suggest using arrays as it’s cleaner using dictionaries.

Will this ever break?

There is a chance this might stop or break. It’s being hosted on Vercel and I have no access to the hosting part of it. All I write is the server code on how requests work to that. But if incorrect data is sent to the server, it wont break.

Can someone edit my data without permission?

As this module is open source (technically) I can’t avoid people reverse-programming the module to get access to the database. Unless they know your ID and SCOPE they wont be able to set/get any data.

Is it better than Roblox Datastore?

The saving and loading of data itself is much simpler and things such as errors are handled automatically using pcall(). It might not be better or as secure as Roblox’s DatastoreService or things like ProfileService but it is a good alternative. It also uses Google’s Firebase for the saving and loading.

4 Likes

I rather use ProfileService and save to Roblox’s Datastores than save to Firebase which I don’t know if it’s free/how it works/if they will delete my data/if you will delete my data. (is it saving to your firebase or mine?)

Anyway I’ll just use ProfileService. It works and is really robust and made by one of the best developers and used in tons of big games.

Thanks for the effort though!

EDIT:

So basically everyone is using the same Firebase :joy: and you have to hope they don’t have your key? What if Firebase has an API to query the keys? This seems super sus.

5 Likes

https://cactus-base.vercel.app/api

1 Like

I use a custom server script, and anything that isn’t correct wont work. Only specific requests work. I have no way to get the firebase API key returned.

And @RickAstll3y there’s almost nothing you can do with the link anyway.

1 Like


Then remove this.

6 Likes

How do I send HTTP requests without the link?

2 Likes

Why are you encoding and decoding it then?

No reason to use this since you can set up your own
firebase or your own reliable mongodb/heroku combo

2 Likes

If you’re saving this to the same FireBase app for everyone’s data, then you are going to get rate-limited so fast. There is a maximum of 360MB per day for the Realtime Database. I have my own Firebase setup, and I hit that limit so quickly with ~900 players. You also won’t be able to validate the data coming through, and this is probably something that is against the Firebase T&C though I’m not too sure. If you aren’t on the free plan yourself, then you are going to end up with a large bill at the end of this.

@batteryday You’re right about the data security part, however ProfileService is made for saving player data. If you go deeper into external data saving services you’ll find they’re incredibly useful for stuff you want to change without restarting your servers. I use this to turn on and off flags such as trading. Most of the top games on Roblox also use this.

If you presented this resource as something similar to RoBase where you create your own Firebase application, then this resource would be useful, however, it seems you’ll run into more harm than good utilising it. I also wouldn’t put any contents of this in ReplicatedStorage, as I am pretty certain local players can gain access to what is being sent through third party tools.

3 Likes

This. And also, what happens when your free plan runs out? That would mean nobody using your module can read or write data. What’s stopping someone from spamming the Firebase database and draining your bank account?

3 Likes

It uses the Cloud Firestore (renamed to Firestore). So it’s not the Realtime Database.

1 Like

It was a random project I wanted to make open source, but that leads to a bigger can of worms for security. Although yeah I’m using the free service and don’t make any changes on my own to any of the data.

Anyone using the module normally will have gameId joined with the id and scope so the same ID and SCOPE can be used by different games. But you’ll need the same gameid, id, and scope to be able to edit data.

What’s stopping someone from spamming the Firebase database and draining your bank account?

That’s another issue, there’s no way to stop. Or so I think. I’m using python as a backend and using the built in http.server library. If anyone knows how to make it more secure be my guest. I don’t want to add in a global debounce since that’s just stupid, and anyone can make multiple scripts to get around that.

Also hi soup :wave:

2 Likes

Honeslty there’s no need to encode and decode. But it’s safer than any random person only getting the module for the api link.

Either way it’s already leaked and I don’t really care if someone gets it. The security relies on the dev themselves and how secure they want to make their key. And the fact that they shouldn’t leak it.

If and when roblox releases their secret type and it works the way I’m thinking it does (like env vars or environ) then I could make a custom GUID and make it slightly more secure.

1 Like