Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

Table wont save to database?

When event fired it suppose to save the table to the databse. Uses FireBase. it ends up removing the KickLogs. How Do I fix this?

local FirebaseService = require(SSS.ServerScripts.DataBase.FirebaseService);


local MasterSettings = FirebaseService:GetFirebase("MasterSettings");

local BanLogLocation = MasterSettings:GetAsync("Moderation/logs/BanLogs/");

local KickLogLocation = MasterSettings:GetAsync("Moderation/logs/KickLogs/");


--------------------------------SAVING

local BanLogs = {}

local KickLogs = {}

	
AdminEvents.KickPlayer.OnServerEvent:connect(function(player, playerToKick, reason) -- Kick
	table.insert(KickLogs, "Test")
	print(KickLogs)
	wait(1)
	MasterSettings:SetAsync("Moderation/logs/KickLogs/", KickLogs);
end)

EDIT 2:

local KickLogs = MasterSettings:GetAsync("Moderation/logs/KickLogs/");

AdminEvents.KickPlayer.OnServerEvent:Connect(function(player, playerToKick, reason) -- Kick
	if IsAdmin == true then
		wait(0.5)
		local function OnUpdate(OldData)
			--Will be new data, If no OldData (In cases where you
			--\save the data for the first time) become emty table.
			
			local NewData = OldData or {};

			table.insert(NewData, "test log");

			return NewData;
		end

		MasterSettings:UpdateAsync("Moderation/logs/KickLogs/", KickLogs, OnUpdate);
	end
end)

1 comment

0

BTW: It saves MasterSettings:SetAsync("Moderation/logs/KickLogs/", "TEST");

1 answer

✓ Accepted answer

It saves it as you say but you do not load it from the cloud, by that i mean KickLogLocation is unused and KickLogs is empty, which means every time you save it you save empty table with you new value, but when rejoining you are not using the saved data. In your case KickLogLocation is never used, not once.

Of course you can fix that by setting KickLogs to loaded save from the cloud

local KickLogs = MasterSettings:GetAsync("Moderation/logs/KickLogs/");

AdminEvents.KickPlayer.OnServerEvent:connect(function(player, playerToKick, reason) -- Kick
	table.insert(KickLogs, "Test")
	print(KickLogs)
	wait(1)
	MasterSettings:SetAsync("Moderation/logs/KickLogs/", KickLogs);
end)

That should fix that because now you actually restore the data, the problem is tho that it's ugly, for me at least, that's why you use UpdateAsync! It's similar to SetAsync but if you have 2 admins on different servers, you are going to lose data because your table does not share between servers so both of ya gamers are going to save moderation claims into different tables and then saving them, overriding what the other admin on the other server saves.

UpdateAsync has cool feature, it returns previous data if any found, with that in your case you are always going to add new kick log to the newest table from the cloud! In your case it would look like this

--/This does not even has to be used with UpdateAsync
local KickLogs = MasterSettings:GetAsync("Moderation/logs/KickLogs/");

AdminEvents.KickPlayer.OnServerEvent:connect(function(player, playerToKick, reason) -- Kick
	print(KickLogs)
	-- wait(1)

	local function OnUpdate(OldData)
		--/NewData is going to be the data we save
		--/If OldData does not exist (In cases where you
		--\save the data for the first time) it switches to
		--\and empty table
		local NewData = OldData or {};

		table.insert(NewData, "Test");

		return NewData;
	end

	MasterSettings:UpdateAsync("Moderation/logs/KickLogs/", KickLogs, OnUpdate);
end)

Third argument of UpdateAsync is a function, this function returns the OldData which is previously saved data. Whatever the OnUpdate function returns will be saved into the cloud, if you return nil, nothing is going to be saved, by that i mean nothing will change, it wont' save nil.

You of course should be also using pcalls because in some cases if data store errors, your script will stop and your logs won't work, not a problem in your case because when server restarts nothing is going to get lost but in some cases it does actually lead to data loss.

I actually noticed one thing in your script, of course i am one of those people who does not care about exploiters but even i would create a simple check if player who is sending the remote is admin!!!!!!!!! Any exploiter can send this remote and the player is going to get kick logged which is not what you want!!!! Implement simple system like this

local Admins = {"kirda", "MegaSpaheggti"}

AdminEvents.KickPlayer.OnServerEvent:connect(function(player, playerToKick, reason) -- Kick
	if not (table.find(Admins, player.Name)) then
		player:Kick("you exploit");
		return;
	end

	print(KickLogs)
	...

table.find will look if player.Name is found in the Admins table, if it was not found it will return nil which will pass the if statement and kick the exploiter!

###UpdateAsync ###pcall ###table.find

##Edit Turns out i am blind, since UpdateAsync knows what you are going to save, you don't need second argument, change

MasterSettings:UpdateAsync("Moderation/logs/KickLogs/", KickLogs, OnUpdate);

to

MasterSettings:UpdateAsync("Moderation/logs/KickLogs/", OnUpdate);

It already knows that KickLogs table is going to be saved from OnUpdate return!!

9 comments

0

Oh I see! I never knew you could use UpdateAsync. This is very helpful info, also I was just testing the event out of the main script. The Main one checks if IsAdmin == true. Thanks! Ill have to try this out on studio!

0

Hmmm I just tried it and I get "attempt to call a string value "

0

Which line exactly? This might have to do something with the MasterSettings as that's only thing in the script i don't have access to. I also did not notice before but :connect() is deprecated, use :Connect() for new work.

0

Check my EDIT 2 Above, I get " ServerScriptService.ServerScripts.DataBase.I also get "FirebaseService:132: attempt to call a string value " And thats coming from the FrireBaseService

0

i made such a dumb mistake, i will edit my post.

0

Hmmm now im getting invalid argument #1 to 'insert' (table expected, got string). Where it tries inserting the new table

0

this means OldData was a string i assume, you did not tell which line tho, if so then make a check that: type(OldData) == "table". And if not, set it to empty table too because you previously could save string.

0

I dont fallow on the type(OldData) == "table" part. Do you mean like if OldData then?

0

nono this part is not in script i posted, you need to add it into the [OnUpdate] function because this checks that [OldData] is a table, if it's not a table you can then also do: OldData = {}, which will override previous data type into a blank table.

This discussion is preserved as it was. New answers, comments, and votes are closed.