Help with setting and removing data from a data stores [URGENT]

I am having trouble setting and removing data from a data store. Here is my script:

local DataStoreService = game:GetService("DataStoreService")
local RankedStore = DataStoreService:GetDataStore("RankedStore")

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local addPlayer = ReplicatedStorage.FireAddPlayer
local removePlayer = ReplicatedStorage.FireRemovePlayer

addPlayer.OnServerEvent:Connect(function(player, name)
	local success, errorMessage = pcall(function()
		RankedStore:SetAsync(name, "passed")
	end)
	if not success then
		print(errorMessage)
	end
	if success then
		print(name.. " added")
	end
end)

removePlayer.OnServerEvent:Connect(function(plr, name)
	local success, errorMessage = pcall(function()
		RankedStore:RemoveAsync(name)
	end)
	if success then
		print(name.." removed")
	end
	if not success then
		print(errorMessage)
	end
end)

It used to work, but now it won’t work anymore. How do I fix this?

You should provide us at least some logs from your console, so we could properly find an issue in your code.

You should use ReplicatedStorage:WaitForChild("FireAddPlayer") since your events could still be in a middle of replication process so they basically don’t exist.

When and where are you calling these events?

1 Like

I added in the :WaitForChild, and it still won’t work. Here is where I fire remove player:

local label = script.Parent
local button = label.Ranked
local text = label.Text

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remove = ReplicatedStorage:WaitForChild("FireRemovePlayer")

button.Activated:Connect(function()
	remove:FireServer(text)
	label:Destroy()
end)

Here’s where I fire AddPlayer:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local addPlayer = ReplicatedStorage:WaitForChild("FireAddPlayer")

local question10 = testingFrame.Question10
local qTenOption1 = question10.Option1
local qTenOption2 = question10.Option2
local qTenOption3 = question10.Option3
local qTenOption4 = question10.Option4
local qTenQuestion = question10.QuestionInstructions

local applicationResults = testingFrame.EndingSequence.ApplicationResults

local correctAnswers = {}

qTenOption1.MouseButton1Up:Connect(function()
	qTenOption1.Visible = false
	qTenOption2.Visible = false
	qTenOption3.Visible = false
	qTenOption4.Visible = false
	qTenQuestion.Visible = false
	applicationResults.Visible = true
	table.insert(correctAnswers, "Question10")
	if #correctAnswers == 10 then
		applicationResults.Text = "Congratulations!!! You have passed the Antarctic Eats Application! Within the next 24 hours, you will be ranked to trainee. You can now clean to earn points, but you can't do anything else. To become a chef, look for the next training in the calendar in the handbook and go to it. Good luck! You may now leave."
		addPlayer:FireServer(player.Name)
	else
		applicationResults.Text = "Unfortunately, you have missed one or more questions, so you have failed. I suggest reading over the handbook and trying again. You may now leave."
	end
end)

It’s also printing that the names are added and removed, but it doesn’t really add and remove them.

1 Like

Where do you exactly check that the player is added or removed except for the logs? Remember that if you’re firing an event addPlayer and then right away fire event getPlayer, this won’t work, since the event addPlayer needs time to add the player to the DataStore. So it would be good, to send addPlayer event, the event will fire back playerAdded and then you can fire getPlayer or something similar to it.

2 Likes

Here’s what shows in the logs:
Screenshot 2022-06-24 131145

Screenshot 2022-06-24 131345

Screenshot 2022-06-24 131411

In each of these, when it says, “ui request sent for ___”, it’s just reading what’s in the DataStore. In the first one, that’s after the addPlayer event is fired. As you can see, it shows that I was added to the Data store. In the second one, you can see that it actually didn’t add me, because it didn’t read me as part of the data store. The second one is after the removePlayer event is fired. It says that I was removed, but in the third one, it shows that I’m still there.

I’m not reading the data store right after a player is added or removed, but I am leaving right after the event is fired, so I could be giving it not enough time.

Another thing I though of is that when I’m reading it, I stop reading too soon. Here is the script that reads it:

local Players = game:GetService("Players")

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local addGui = ReplicatedStorage.FireAddGUI

local DataStoreService = game:GetService("DataStoreService")
local rankedStore = DataStoreService:GetDataStore("RankedStore")

Players.PlayerAdded:Connect(function(plr)
	if plr:GetRankInGroup(11635716) >= 254 then
		local success, pages = pcall(function()
			return rankedStore:ListKeysAsync()
		end)
		
		if success then
			local passed = {}

			while task.wait(0.1) do		
				for i, v in pairs(pages:GetCurrentPage()) do
					table.insert(passed,v)
					print("Player added to passed")
				end

				if pages.IsFinished == true then
					print("Pages finished")
					break
				end
				
				print("next page")
				pages:AdvanceToNextPageAsync()
			end	

			for i, name in pairs(passed) do
				addGui:FireClient(plr,name.KeyName)
				print("ui request sent for "..name.KeyName)
			end
		end
	end
end)

Here’s what it looks like in the output window:
Screenshot 2022-06-24 132623

1 Like

You should do it as I wrote before. Send an event to the server, server will process and lock thread until datastore write is completed (pcall), then the server fires an event to the client, client will fire another event to the server with getPlayer, at this time, it should be alright.

Don’t do it with something like wait, because it still doesn’t guarantees you the result. The datastore write time is variable, it could be 30ms, it could be 2000ms, depends on Roblox servers. So the best and guaranteed way is to create a pipeline of events => Client(addPlayer) -> Server(playerAdded) -> Client(getPlayer) -> Server(Print the player from datastore).

2 Likes

Sorry I’m not really understanding what to do. How do I check that the datastore write is completed? Btw, I’m not reading the datastore right after it’s written. It is supposed to be long after. The game is a test, so if the player passes, they will be added to the datastore. Later, when I get on, the server will read all items of the datastore and create a gui for each of them. The datastore isn’t being read immediately after a player is added or removed.

1 Like

right after this line add … RankedStore:RemoveAsync(name)
wait(6)
– you could add an error right here to just exit

This should get you back to working …
You can then rem if off and use it as needed to remove any data that may be in error.

Or you could use DataStore Editor plugin.

2 Likes

Could you please explain more in depth what to do? Could you show what the script would look like after I add that stuff?

1 Like

Most the time when you get a data error … as in you made a mistake. That data is saved and keeps coming back with the same error. Making a working script not so working anymore. You can’t fix the script because the data it’s reading is wrong. I’m assuming this is happing to you atm. The line I placed after the on add player function is just a temporary one liner to remove that data. Once removed you can then go back to editing to find whatever problem you’re having. This is not a fix for your script. It’s a way to get back to fixing your script. This can also be done with that DataStore Editor Plugin. There is nothing really to explain to it more than that or what I’ve posted.

2 Likes

I changed it to this, but it still not working:

local DataStoreService = game:GetService("DataStoreService")
local RankedStore = DataStoreService:GetDataStore("RankedStore")

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local addPlayer = ReplicatedStorage:WaitForChild("FireAddPlayer")
local removePlayer = ReplicatedStorage:WaitForChild("FireRemovePlayer")

addPlayer.OnServerEvent:Connect(function(player, name)
	local success, errorMessage = pcall(function()
		RankedStore:RemoveAsync(name)
	end)
	if not success then
		print(errorMessage)
	end
	local success, errorMessage = pcall(function()
		RankedStore:RemoveAsync("Instance")
	end)
	if not success then
		print(errorMessage)
	end
	wait(6)
	local success, errorMessage = pcall(function()
		RankedStore:SetAsync(name, "passed")
	end)
	if not success then
		print(errorMessage)
	end
	if success then
		print(name.. " added")
	end
end)

removePlayer.OnServerEvent:Connect(function(plr, name)
	local success, errorMessage = pcall(function()
		RankedStore:RemoveAsync(name)
	end)
	if success then
		print(name.." removed")
	end
	if not success then
		print(errorMessage)
	end
end)

Did I do it correctly?

Since I’m having trouble, should I just uninstall and reinstall studio?

You only need to do that RankedStore:RemoveAsync once to clear the old data that was creating the error when read. Don’t need the wait(6) … and you’re clearing again when you quit. hold on .

1 Like

Make sure you have API set to on for this program
Copy script to a non-Localscript and place in ServerScriptService

local dataStoreService = game:GetService("DataStoreService")
local dataKey = dataStoreService:GetOrderedDataStore("Coins")

game.Players.PlayerAdded:Connect(function(plr)
	-- dataKey:RemoveAsync(plr.UserId) wait(3)	
	--^ this is a reset data if the -- is removed 
		
	local ls = Instance.new("Folder")
	ls.Name = "leaderstats" ls.Parent = plr
	local cn = Instance.new("IntValue")
	cn.Name = "Coins" cn.Parent = ls

	local sus, err = pcall(function()
		ls:WaitForChild("Coins").Value =
			(dataKey:GetAsync(plr.UserId, "Coins") or 0)
	end) if not sus then warn(err) end wait()
end)
game.Players.PlayerRemoving:Connect(function(plr)
	local sus, err = pcall(function()
		dataKey:SetAsync(plr.UserId,
			(plr.leaderstats.Coins.Value))
	end) if not sus then warn(err) end wait()
end)

wait(3) -- test: give all players a coin
local players = game:GetService("Players")
for _, player in pairs (players:GetPlayers()) do
	if player:FindFirstChild("leaderstats") ~= nil then
		local coins = player.leaderstats.Coins.Value
		
		coins = coins + 1
		player.leaderstats.Coins.Value = coins
		
		local sus, err = pcall(function()
			dataKey:SetAsync(tonumber(player.UserId),
				player.leaderstats.Coins.Value)
		end) if not sus then warn(err) end
	end
end

This is just a basic set up. But this will show you how you call all this.
I’m sure there are better ways and/or things you will wish to add.
This is also set up for testing and why it has the RemoveAsync in it.
If there are no errors it will not need the RemoveAsync at all.

1 Like

I’ve tried everything. I’ve even tried uninstalling and reinstalling studio, but it still won’t work. Since that store had an error, I created a different store, and it still won’t work. Can you please be more descriptive? I can’t really figure out anything from the script you sent because you didn’t show how to use RemoveAsync, which is the part I’m having trouble with.

You un-rem that RemoveAsync statment … (remove the two – in front of the line)
Then run it again. Should come up totally reset. But it will set itself up again right after.
If you wish to just reset and stop, make a new script to use just for doing this and turn off the other one for the moment.

local dataStoreService = game:GetService("DataStoreService")
local dataKey = dataStoreService:GetOrderedDataStore("Coins")

game.Players.PlayerAdded:Connect(function(plr)
	 dataKey:RemoveAsync(plr.UserId) wait(3)	
end)

That by itself should remove the data in the key. Then you can start fresh without the error that data had.

1 Like

I don’t know how you’re sitting for Robuks but there is a DataStore Editor in the plugins you can buy that will let you edit out bad data just like that call I posted. But, you can see all the data and work with it right there. As in you can remove it if needed. Your problem isn’t with the studio.

1 Like

Why are you trusting remote events for your datastores? Players can spam the living hell out of your remote events and essentially flood the queue with unnecessary requests.

1 Like

The only remote events I’m using there is when you log on and when you log off. Good luck spamming that.