game.Players:GetNameFromUserIdAsync() not working in OrderedDataStores

Ok, so I have tried to make a leaderboard with OrderedDataStores, there you would see the top 5 with the most wins, but for some reason it doesn’t work and I get this error: " Players:GetNameFromUserId() failed because HTTP 404 (NotFound)", Then I tried to debug it by printing the key, and it printed me -2(?), I have also tried to re-write my script and it also didn’t work.

Code here:

local DTS = game:GetService("DataStoreService")
local WinsStore = DTS:GetOrderedDataStore("WinsStore")
local PlayersInLeaderBoard = workspace.WinsLeaderboard.SurfaceGui:WaitForChild("Users")


game.Players.PlayerAdded:Connect(function(plr)
	
	
	local leaderstats = Instance.new("Folder")
	leaderstats.Parent = plr
	leaderstats.Name = "leaderstats"
	
	
	local Wins = Instance.new("NumberValue")
	Wins.Parent = leaderstats
	Wins.Name = "Wins"
	
	
end)




local function updateLeaderboard()
	local success, errormessage = pcall(function()
		local Data = WinsStore:GetSortedAsync(false, 5)
		local currentpage = Data:GetCurrentPage()
		for rank, data in ipairs(currentpage) do
			local username = game.Players:GetNameFromUserIdAsync(tonumber(data.key))
			local name = username
			local rankofplayer = rank
			local winsofplayer = tostring(data.value)
			local IsOnLeaderboard = false
			
			
			if winsofplayer and not IsOnLeaderboard then
				local cloneframe = game.ReplicatedStorage.FrameOfPlayer:Clone()
				cloneframe.Parent = PlayersInLeaderBoard
				cloneframe.NumberOfPlayer.Text = rankofplayer
				cloneframe.Username.Text = name
				cloneframe.Wins.Text = winsofplayer
				cloneframe.Position = UDim2.new(0, PlayersInLeaderBoard.Position.Y.Scale, 0, 0 + 0.3, #PlayersInLeaderBoard:GetChildren(), 0, 0)
				IsOnLeaderboard = false
			end
		end
	end)
	if not success then
		print(errormessage)
	end
end


while true do
	for _, plr in pairs(game.Players:GetPlayers()) do
		WinsStore:SetAsync(plr.UserId, plr.leaderstats.Wins.Value)
	end
	
	for _, frame in pairs(PlayersInLeaderBoard:GetChildren()) do
		frame:Destroy()
	end
	updateLeaderboard()
	wait(10)
end```
1 Like

[snipped because it turned out to be wrong]


As a side note:

while true do
	for _, plr in pairs(game.Players:GetPlayers()) do
		WinsStore:SetAsync(plr.UserId, plr.leaderstats.Wins.Value)
	end

Please DO NOT constantly write to a DataStore; you’ll be throttled, which can hold up other attempts to write to the DataStore, and if the queue fills up, you can suffer from data loss. Instead, in this case you should write the player’s wins to the DataStore when they leave, which you can do using the Players.PlayerRemoving event.

1 Like

It still doesn’t work, now I get that argument 1 missing or nil.

1 Like

Can you post the code you wrote to access the entries of data now?

1 Like
local DTS = game:GetService("DataStoreService")
local WinsStore = DTS:GetOrderedDataStore("WinsStores")
local PlayersInLeaderBoard = workspace.WinsLeaderboard.SurfaceGui:WaitForChild("Users")


game.Players.PlayerAdded:Connect(function(plr)
	
	
	local leaderstats = Instance.new("Folder")
	leaderstats.Parent = plr
	leaderstats.Name = "leaderstats"
	
	
	local Wins = Instance.new("NumberValue")
	Wins.Parent = leaderstats
	Wins.Name = "Wins"
	
	
end)




local function updateLeaderboard()
	local success, errormessage = pcall(function()
		local Data = WinsStore:GetSortedAsync(false, 2)
		local currentpage = Data:GetCurrentPage()
		for rank, data in ipairs(currentpage) do
			for userid, value in pairs(data) do
			local username = game.Players:GetNameFromUserIdAsync(tonumber(userid))
			local name = username
			local rankofplayer = rank
			local winsofplayer = tostring(value)
			local IsOnLeaderboard = false
			for i, v in pairs(PlayersInLeaderBoard:GetChildren()) do
				if v.Username.Text  == name then
					IsOnLeaderboard = true
					break
				end
			end
			
			if winsofplayer and not IsOnLeaderboard then
				local cloneframe = game.ReplicatedStorage.FrameOfPlayer:Clone()
				cloneframe.Parent = PlayersInLeaderBoard
				cloneframe.NumberOfPlayer.Text = rankofplayer
				cloneframe.Username.Text = name
				cloneframe.Wins.Text = winsofplayer
				cloneframe.Position = UDim2.new(0, PlayersInLeaderBoard.Position.Y.Scale, 0, 0 + 0.3, #PlayersInLeaderBoard:GetChildren(), 0, 0)
			end
			end
		end
	end)
	if not success then
		print(errormessage)
	end
end


while true do
	for _, plr in pairs(game.Players:GetPlayers()) do
		WinsStore:SetAsync(plr.UserId, plr.leaderstats.Wins.Value)
	end
	
	for _, frame in pairs(PlayersInLeaderBoard:GetChildren()) do
		frame:Destroy()
	end
	updateLeaderboard()
	wait(10)
end```
Here you go.

OH I’m an idiot. Just read this page on the documentation for DataStorePages:

each containing keys named key and value

You were correct in the beginning; the key is literally named "key". You should change it back; my mistake.

It seems that the key you’re getting out was -2 based on the original post. Are you testing this using the Client and Servers section in the Studio toolbar?

I tested it when joining the game in studio, there it printed in output -2

Have you tried just printing out all the keys and values in data and not doing anything with it? It might be possible that the entire script actually works but some invalid values somehow snuck its way into the DataStore and it’s tripping up everything right now.

I also had the same problem before, so I re-wrote my entire script and I still have that problem.

I tried to print the rank of the player, it worked and said 1 (cause I am the only player so I am first), then I tried to print data.value, it also worked and printed my wins, but data.key only printed -2 and not the UserId.

Alright the only thing I can think of is this:
WinsStore:SetAsync(plr.UserId, plr.leaderstats.Wins.Value)

instead of
plr.UserId

try
tostring(plr.UserId)

since the keys have to be strings. If this doesn’t work then I genuniely have 0 idea what’s going on.

It still doesn’t work when I change it, BUT when i change the number 2 in WinsStore:GetSortedAsync() to 1 it somehow works (?) (but only if I change it to 1 and no other number)

I’m guessing the error has to do with the lack of sufficient data entries in the DataStore.

Maybe try just putting in some dummy values (e.g. get the IDs of some of your friends’ accounts and just put in 0 for their wins) as placeholders.

Additionally, you could add a check to make sure the UserId is reasonable before trying to use it to query Roblox, i.e. do

for userid, value in pairs(data) do
    if userid > 0 then
        local username = game.Players:GetNameFromUserIdAsync(tonumber(userid))
        local name = username
        -- etc
4 Likes

Yessss, it is working now, but now it says that I am second place even though I should be first place…?

Nevermind, I also fixed that one, thanks for helping. :slight_smile:

This happened to me too so I just made a new datastorw with other key