Global leaderboards and GetUserIdAsync

I have three leaderboards. One of them I working and the other two are not. I made it so that they print the data keys(players’ user ids) inside of them. The first leaderboard works fine and prints the correct things but the other two do not. Also, they only print inside of studio and not in a normal server. I know why this happened but I do not know how to fix it. This happened as I opened a studio test server and the “bots” have user ids, -1 to -3, so the get userid async did not work. Here is a link to a similar topic which confusing me:What's this error and how do I fix it? (Global leaderboards) - #16 by wevetments. Here are the prints: Capture2
Here is my script:

 local DataStoreService = game:GetService("DataStoreService")
local WinsLeaderboard = DataStoreService:GetOrderedDataStore("ObbyData")
local WinsLeaderboard1 = DataStoreService:GetOrderedDataStore("AvgDStore")
local WinsLeaderboard2 = DataStoreService:GetOrderedDataStore("ObbyDatas")

local function updateLeaderboard()
        local success, errorMessage = pcall (function()
                local Data =WinsLeaderboard:GetSortedAsync(false, 5)
                local WinsPage = Data:GetCurrentPage()
		                for Rank, data in ipairs(WinsPage) do
			print(data.key)
			                       local userName = game.Players:GetNameFromUserIdAsync(tonumber(data.key))
			
                       local Name = userName
                       local Seconds = data.value
                       local isOnLeaderboard = false
                       for i, v in pairs(game.Workspace.Locations.Leaderboardarea.LeaderboardArea.Leaderboard.LeaderboardGUI.Holder:GetChildren()) do
                             if v.Name2.Text == Name then
                                  isOnLeaderboard = true
                                  break
                           end
                    end

                     if Seconds and isOnLeaderboard == false then
                            local newLbFrame = game.ReplicatedStorage:WaitForChild("LeaderboardFrame"):Clone()
                            newLbFrame.Name2.Text = Name
                            newLbFrame.TimeSpent.Text = Seconds
                            newLbFrame.Rank.Text = "#"..Rank
                            newLbFrame.Position = UDim2.new(0, 0, newLbFrame.Position.Y.Scale + (.008 * #game.Workspace.Locations.Leaderboardarea.LeaderboardArea.Leaderboard.LeaderboardGUI.Holder:GetChildren()), 0)
				                            newLbFrame.Parent = game.Workspace.Locations.Leaderboardarea.LeaderboardArea.Leaderboard.LeaderboardGUI.Holder 
				
                     end
              end
      end)

      if not success then
            print(errorMessage)
      end
end
local function updateLeaderboard1()
	
        local success, errorMessage = pcall (function()
                local Data =WinsLeaderboard1:GetSortedAsync(true, 5)
                local WinsPage = Data:GetCurrentPage()
		                for Rank, data in ipairs(WinsPage) do
			print(data.key)
                       local userName = game.Players:GetNameFromUserIdAsync(tonumber(data.key))
                       local Name = userName
			                       local AvgD = data.value
		
                       local isOnLeaderboard = false
                       for i, v in pairs(game.Workspace.Locations.Leaderboardarea.LeaderboardArea3.Leaderboard.LeaderboardGUI.Holder:GetChildren()) do
                             if v.Name2.Text == Name then
                                  isOnLeaderboard = true
                                  break
                           end
                    end

                     if AvgD and isOnLeaderboard == false then
                            local newLbFrame = game.ReplicatedStorage:WaitForChild("LeaderboardFrame"):Clone()
                            newLbFrame.Name2.Text = Name
                            newLbFrame.TimeSpent.Text = AvgD 
                            newLbFrame.Rank.Text = "#"..Rank
                            newLbFrame.Position = UDim2.new(0, 0, newLbFrame.Position.Y.Scale + (.008 * #game.Workspace.Locations.Leaderboardarea.LeaderboardArea3.Leaderboard.LeaderboardGUI.Holder:GetChildren()), 0)
                            newLbFrame.Parent = game.Workspace.Locations.Leaderboardarea.LeaderboardArea3.Leaderboard.LeaderboardGUI.Holder 
                     end 
			              end
			
		      end)
		

      if not success then
            print(errorMessage)
      end
end
local function updateLeaderboard2()
        local success, errorMessage = pcall (function()
                local Data =WinsLeaderboard2:GetSortedAsync(true, 5)
                local WinsPage = Data:GetCurrentPage()
		                for Rank, data in ipairs(WinsPage) do
			print(data.key)
                       local userName = game.Players:GetNameFromUserIdAsync(tonumber(data.key))
                       local Name = userName
                       local Deaths = data.value
                       local isOnLeaderboard = false
                       for i, v in pairs(game.Workspace.Locations.Leaderboardarea.LeaderboardArea2.Leaderboard.LeaderboardGUI.Holder:GetChildren()) do
                             if v.Name2.Text == Name then
                                  isOnLeaderboard = true
                                  break
                           end
                    end

                     if Deaths and isOnLeaderboard == false then
                            local newLbFrame = game.ReplicatedStorage:WaitForChild("LeaderboardFrame"):Clone()
                            newLbFrame.Name2.Text = Name
                            newLbFrame.TimeSpent.Text = Deaths
                            newLbFrame.Rank.Text = "#"..Rank
                            newLbFrame.Position = UDim2.new(0, 0, newLbFrame.Position.Y.Scale + (.008 * #game.Workspace.Locations.Leaderboardarea.LeaderboardArea2.Leaderboard.LeaderboardGUI.Holder:GetChildren()), 0)
                            newLbFrame.Parent = game.Workspace.Locations.Leaderboardarea.LeaderboardArea2.Leaderboard.LeaderboardGUI.Holder 
                     end
              end
      end)

      if not success then
            print(errorMessage)
      end
end
local g =0
wait(8)
while true do

	        for _, player in pairs(game.Players:GetPlayers()) do
		local Avg =  math.floor(player.leaderstats["Avg Deaths"].Value + 0.5)
		              WinsLeaderboard:SetAsync(player.UserId, player.leaderstats.Seconds.Value)
		WinsLeaderboard2:SetAsync(player.UserId, player.leaderstats.Deaths.Value)
		WinsLeaderboard1:SetAsync(player.UserId, Avg)
        end

        for _, frame in pairs (game.Workspace.Locations.Leaderboardarea.LeaderboardArea.Leaderboard.LeaderboardGUI.Holder:GetChildren()) do
              frame:Destroy()
	        end
	
        for _, frame in pairs (game.Workspace.Locations.Leaderboardarea.LeaderboardArea2.Leaderboard.LeaderboardGUI.Holder:GetChildren()) do
              frame:Destroy()
	        end
	for _, frame in pairs (game.Workspace.Locations.Leaderboardarea.LeaderboardArea3.Leaderboard.LeaderboardGUI.Holder:GetChildren()) do
              frame:Destroy()
	        end
        updateLeaderboard()
	updateLeaderboard1()
	updateLeaderboard2()	 
       
	g = g+1
	        print("Updated Seconds,Deaths and Average Deaths Leaderboards!",g)


        wait(60)
end	

	

:GetNameFromUserId(id) uses api to get the players name by their id. If that UserId doesn’t exist then it can’t get the username.

You can use a pcall to get around this.

local name = ""
local id = -1

local Success, Error = pcall(function()
    name = players:GetNameFromUserId(id) -- // this will error if a username can't be grabbed
end)

if not Success then -- // something went wrong, in this case the script couldn't get the Username from the provided ID because a player with that ID doesn't exist.
    name = "Bot " .. tostring(id) -- // set name to something else
end
-- rest of your script
3 Likes

Do I put this right at the top of my script?

Put it where-ever you need to get the name of the player.

1 Like

These are the variable I use:

local userName = game.Players:GetNameFromUserIdAsync(tonumber(data.key))
local Name = userName

So how can i change your script to fit it?

You can make my code into a function.

local function getNameFromUserIdAsync(id) -- // wrap my code in a function
    local name = ""

    local Success, Error = pcall(function()
        name = players:GetNameFromUserId(id) -- // this will error if a username can't be grabbed
    end)

    if not Success then -- // something went wrong, in this case the script couldn't get the Username from the provided ID because a player with that ID doesn't exist.
        name = "Bot " .. tostring(id) -- // set name to something else
    end
    return name -- // send name back
end

Here is an example of how to use this in your use case.

local id = -1
local Name = getNameFromUserIdAsync(id) -- // because i returned "name" in my function, this will be set to whatever "name" was.
1 Like

It does not work, the leaderboards just show bot. :

 local DataStoreService = game:GetService("DataStoreService")
local WinsLeaderboard = DataStoreService:GetOrderedDataStore("ObbyData")
local WinsLeaderboard1 = DataStoreService:GetOrderedDataStore("AvgDStore")
local WinsLeaderboard2 = DataStoreService:GetOrderedDataStore("ObbyDatas")
local players = game:GetService("Players")
local name = ""
local id = -1


local function updateLeaderboard()
        local success, errorMessage = pcall (function()
                local Data =WinsLeaderboard:GetSortedAsync(false, 5)
                local WinsPage = Data:GetCurrentPage()
		                for Rank, data in ipairs(WinsPage) do
			print(data.key)
local function getNameFromUserIdAsync(id) 
    local name = ""

    local Success, Error = pcall(function()
        name = players:GetNameFromUserId(id)
    end)

    if not Success then 
        name = "Bot " .. tostring(id) 
    end
    return name 
end

			
                       local Name = getNameFromUserIdAsync(id)
                       local Seconds = data.value
                       local isOnLeaderboard = false
                       for i, v in pairs(game.Workspace.Locations.Leaderboardarea.LeaderboardArea.Leaderboard.LeaderboardGUI.Holder:GetChildren()) do
                             if v.Name2.Text == Name then
                                  isOnLeaderboard = true
                                  break
                           end
                    end

                     if Seconds and isOnLeaderboard == false then
                            local newLbFrame = game.ReplicatedStorage:WaitForChild("LeaderboardFrame"):Clone()
                            newLbFrame.Name2.Text = Name
                            newLbFrame.TimeSpent.Text = Seconds
                            newLbFrame.Rank.Text = "#"..Rank
                            newLbFrame.Position = UDim2.new(0, 0, newLbFrame.Position.Y.Scale + (.008 * #game.Workspace.Locations.Leaderboardarea.LeaderboardArea.Leaderboard.LeaderboardGUI.Holder:GetChildren()), 0)
				                            newLbFrame.Parent = game.Workspace.Locations.Leaderboardarea.LeaderboardArea.Leaderboard.LeaderboardGUI.Holder 
				
                     end
              end
      end)

      if not success then
            print(errorMessage)
      end
end
local function updateLeaderboard1()
	
        local success, errorMessage = pcall (function()
                local Data =WinsLeaderboard1:GetSortedAsync(true, 5)
                local WinsPage = Data:GetCurrentPage()
		                for Rank, data in ipairs(WinsPage) do
			print(data.key)
                      local function getNameFromUserIdAsync(id) 
    local name = ""

    local Success, Error = pcall(function()
        name = players:GetNameFromUserId(id)
    end)

    if not Success then 
        name = "Bot " .. tostring(id) 
    end
    return name 
end

			
                       local Name = getNameFromUserIdAsync(id)
			                       local AvgD = data.value
		
                       local isOnLeaderboard = false
                       for i, v in pairs(game.Workspace.Locations.Leaderboardarea.LeaderboardArea3.Leaderboard.LeaderboardGUI.Holder:GetChildren()) do
                             if v.Name2.Text == Name then
                                  isOnLeaderboard = true
                                  break
                           end
                    end

                     if AvgD and isOnLeaderboard == false then
                            local newLbFrame = game.ReplicatedStorage:WaitForChild("LeaderboardFrame"):Clone()
                            newLbFrame.Name2.Text = Name
                            newLbFrame.TimeSpent.Text = AvgD 
                            newLbFrame.Rank.Text = "#"..Rank
                            newLbFrame.Position = UDim2.new(0, 0, newLbFrame.Position.Y.Scale + (.008 * #game.Workspace.Locations.Leaderboardarea.LeaderboardArea3.Leaderboard.LeaderboardGUI.Holder:GetChildren()), 0)
                            newLbFrame.Parent = game.Workspace.Locations.Leaderboardarea.LeaderboardArea3.Leaderboard.LeaderboardGUI.Holder 
                     end 
			              end
			
		      end)
		

      if not success then
            print(errorMessage)
      end
end
local function updateLeaderboard2()
        local success, errorMessage = pcall (function()
                local Data =WinsLeaderboard2:GetSortedAsync(true, 5)
                local WinsPage = Data:GetCurrentPage()
		                for Rank, data in ipairs(WinsPage) do
			print(data.key)
                       local function getNameFromUserIdAsync(id) 
    local name = ""

    local Success, Error = pcall(function()
        name = players:GetNameFromUserId(id)
    end)

    if not Success then 
        name = "Bot " .. tostring(id) 
    end
    return name 
end

			
                       local Name = getNameFromUserIdAsync(id)
                       local Deaths = data.value
                       local isOnLeaderboard = false
                       for i, v in pairs(game.Workspace.Locations.Leaderboardarea.LeaderboardArea2.Leaderboard.LeaderboardGUI.Holder:GetChildren()) do
                             if v.Name2.Text == Name then
                                  isOnLeaderboard = true
                                  break
                           end
                    end

                     if Deaths and isOnLeaderboard == false then
                            local newLbFrame = game.ReplicatedStorage:WaitForChild("LeaderboardFrame"):Clone()
                            newLbFrame.Name2.Text = Name
                            newLbFrame.TimeSpent.Text = Deaths
                            newLbFrame.Rank.Text = "#"..Rank
                            newLbFrame.Position = UDim2.new(0, 0, newLbFrame.Position.Y.Scale + (.008 * #game.Workspace.Locations.Leaderboardarea.LeaderboardArea2.Leaderboard.LeaderboardGUI.Holder:GetChildren()), 0)
                            newLbFrame.Parent = game.Workspace.Locations.Leaderboardarea.LeaderboardArea2.Leaderboard.LeaderboardGUI.Holder 
                     end
              end
      end)

      if not success then
            print(errorMessage)
      end
end
local g =0
wait(8)
while true do

	        for _, player in pairs(game.Players:GetPlayers()) do
		local Avg =  math.floor(player.leaderstats["Avg Deaths"].Value + 0.5)
		              WinsLeaderboard:SetAsync(player.UserId, player.leaderstats.Seconds.Value)
		WinsLeaderboard2:SetAsync(player.UserId, player.leaderstats.Deaths.Value)
		WinsLeaderboard1:SetAsync(player.UserId, Avg)
        end

        for _, frame in pairs (game.Workspace.Locations.Leaderboardarea.LeaderboardArea.Leaderboard.LeaderboardGUI.Holder:GetChildren()) do
              frame:Destroy()
	        end
	
        for _, frame in pairs (game.Workspace.Locations.Leaderboardarea.LeaderboardArea2.Leaderboard.LeaderboardGUI.Holder:GetChildren()) do
              frame:Destroy()
	        end
	for _, frame in pairs (game.Workspace.Locations.Leaderboardarea.LeaderboardArea3.Leaderboard.LeaderboardGUI.Holder:GetChildren()) do
              frame:Destroy()
	        end
        updateLeaderboard()
	updateLeaderboard1()
	updateLeaderboard2()	 
       
	g = g+1
	        print("Updated Seconds,Deaths and Average Deaths Leaderboards!",g)


        wait(60)
end	

	
	
	
	
	

You don’t need to define id and name as global variables. Name and id were used in my code as an example, I’m not going to spoonfeed you code.

You shouldn’t wrap my function in the updateLeaderboard function, it should be independant.

It sets the text to bot because thats what the function sets it to over erroring. The bot’s dont have actual names. You can set name to something else. If you want to make it say Player[x] then you can change the name = "Bot " .. tostring(id) part of my function to name = "Player" .. tostring(id * -1).

2 Likes

I tried what you said but it does not work. Here is my code:

 local DataStoreService = game:GetService("DataStoreService")
local WinsLeaderboard = DataStoreService:GetOrderedDataStore("ObbyData")
local WinsLeaderboard1 = DataStoreService:GetOrderedDataStore("AvgDStore")
local WinsLeaderboard2 = DataStoreService:GetOrderedDataStore("ObbyDatas")
local players = game:GetService("Players")
local name = ""
local id = -1
local function getNameFromUserIdAsync(id) -- // wrap my code in a function
    local name = ""

    local Success, Error = pcall(function()
        name = players:GetNameFromUserId(id) -- // this will error if a username can't be grabbed
    end)

    if not Success then -- // something went wrong, in this case the script couldn't get the Username from the provided ID because a player with that ID doesn't exist.
        name = "Bot " .. tostring(id) -- // set name to something else
    end
    return name -- // send name back
end
local Name1 = getNameFromUserIdAsync(id)

local function updateLeaderboard()
        local success, errorMessage = pcall (function()
                local Data =WinsLeaderboard:GetSortedAsync(false, 5)
                local WinsPage = Data:GetCurrentPage()
		                for Rank, data in ipairs(WinsPage) do
			print(data.key)
			
			                       local userName = game.Players:GetNameFromUserIdAsync(tonumber(data.key))
			
                       local Name = userName
                       local Seconds = data.value
                       local isOnLeaderboard = false
                       for i, v in pairs(game.Workspace.Locations.Leaderboardarea.LeaderboardArea.Leaderboard.LeaderboardGUI.Holder:GetChildren()) do
                             if v.Name2.Text == Name then
                                  isOnLeaderboard = true
                                  break
                           end
                    end

                     if Seconds and isOnLeaderboard == false then
                            local newLbFrame = game.ReplicatedStorage:WaitForChild("LeaderboardFrame"):Clone()
                            newLbFrame.Name2.Text = Name
                            newLbFrame.TimeSpent.Text = Seconds
                            newLbFrame.Rank.Text = "#"..Rank
                            newLbFrame.Position = UDim2.new(0, 0, newLbFrame.Position.Y.Scale + (.008 * #game.Workspace.Locations.Leaderboardarea.LeaderboardArea.Leaderboard.LeaderboardGUI.Holder:GetChildren()), 0)
				                            newLbFrame.Parent = game.Workspace.Locations.Leaderboardarea.LeaderboardArea.Leaderboard.LeaderboardGUI.Holder 
				
                     end
              end
      end)

      if not success then
            print(errorMessage)
      end
end
local function updateLeaderboard1()
	
        local success, errorMessage = pcall (function()
                local Data =WinsLeaderboard1:GetSortedAsync(true, 5)
                local WinsPage = Data:GetCurrentPage()
		                for Rank, data in ipairs(WinsPage) do
			print(data.key)
                       local userName = game.Players:GetNameFromUserIdAsync(tonumber(data.key))
                       local Name = userName
			                       local AvgD = data.value
		
                       local isOnLeaderboard = false
                       for i, v in pairs(game.Workspace.Locations.Leaderboardarea.LeaderboardArea3.Leaderboard.LeaderboardGUI.Holder:GetChildren()) do
                             if v.Name2.Text == Name then
                                  isOnLeaderboard = true
                                  break
                           end
                    end

                     if AvgD and isOnLeaderboard == false then
                            local newLbFrame = game.ReplicatedStorage:WaitForChild("LeaderboardFrame"):Clone()
                            newLbFrame.Name2.Text = Name
                            newLbFrame.TimeSpent.Text = AvgD 
                            newLbFrame.Rank.Text = "#"..Rank
                            newLbFrame.Position = UDim2.new(0, 0, newLbFrame.Position.Y.Scale + (.008 * #game.Workspace.Locations.Leaderboardarea.LeaderboardArea3.Leaderboard.LeaderboardGUI.Holder:GetChildren()), 0)
                            newLbFrame.Parent = game.Workspace.Locations.Leaderboardarea.LeaderboardArea3.Leaderboard.LeaderboardGUI.Holder 
                     end 
			              end
			
		      end)
		

      if not success then
            print(errorMessage)
      end
end
local function updateLeaderboard2()
        local success, errorMessage = pcall (function()
                local Data =WinsLeaderboard2:GetSortedAsync(true, 5)
                local WinsPage = Data:GetCurrentPage()
		                for Rank, data in ipairs(WinsPage) do
			print(data.key)
                       local userName = game.Players:GetNameFromUserIdAsync(tonumber(data.key))
                       local Name = userName
                       local Deaths = data.value
                       local isOnLeaderboard = false
                       for i, v in pairs(game.Workspace.Locations.Leaderboardarea.LeaderboardArea2.Leaderboard.LeaderboardGUI.Holder:GetChildren()) do
                             if v.Name2.Text == Name then
                                  isOnLeaderboard = true
                                  break
                           end
                    end

                     if Deaths and isOnLeaderboard == false then
                            local newLbFrame = game.ReplicatedStorage:WaitForChild("LeaderboardFrame"):Clone()
                            newLbFrame.Name2.Text = Name
                            newLbFrame.TimeSpent.Text = Deaths
                            newLbFrame.Rank.Text = "#"..Rank
                            newLbFrame.Position = UDim2.new(0, 0, newLbFrame.Position.Y.Scale + (.008 * #game.Workspace.Locations.Leaderboardarea.LeaderboardArea2.Leaderboard.LeaderboardGUI.Holder:GetChildren()), 0)
                            newLbFrame.Parent = game.Workspace.Locations.Leaderboardarea.LeaderboardArea2.Leaderboard.LeaderboardGUI.Holder 
                     end
              end
      end)

      if not success then
            print(errorMessage)
      end
end
local g =0
wait(8)
while true do

	        for _, player in pairs(game.Players:GetPlayers()) do
		local Avg =  math.floor(player.leaderstats["Avg Deaths"].Value + 0.5)
		              WinsLeaderboard:SetAsync(player.UserId, player.leaderstats.Seconds.Value)
		WinsLeaderboard2:SetAsync(player.UserId, player.leaderstats.Deaths.Value)
		WinsLeaderboard1:SetAsync(player.UserId, Avg)
        end

        for _, frame in pairs (game.Workspace.Locations.Leaderboardarea.LeaderboardArea.Leaderboard.LeaderboardGUI.Holder:GetChildren()) do
              frame:Destroy()
	        end
	
        for _, frame in pairs (game.Workspace.Locations.Leaderboardarea.LeaderboardArea2.Leaderboard.LeaderboardGUI.Holder:GetChildren()) do
              frame:Destroy()
	        end
	for _, frame in pairs (game.Workspace.Locations.Leaderboardarea.LeaderboardArea3.Leaderboard.LeaderboardGUI.Holder:GetChildren()) do
              frame:Destroy()
	        end
        updateLeaderboard()
	updateLeaderboard1()
	updateLeaderboard2()	 
       
	g = g+1
	        print("Updated Seconds,Deaths and Average Deaths Leaderboards!",g)


        wait(60)
end	

	
	
	
	
	

I am confused with where to put this/what to do with this

local Name1 = getNameFromUserIdAsync(id)

You should not copy and paste code, yes it may work sometimes but you’d not be able to use it in other situations when necessary. My username is deprecatedHeart and I have the UserId of 254941219. If I run this code:

print(game.Players:GetNameFromUserIdAsync(254941219))

It will return my username. Also what @Tom_atoes meant was this part:

local id = -1

This means if you did:

print(id)

It would print out -1. It does not mean anything whatsoever (yes I know -1 is the ID for testers in Studio but it is not necessary in this scenario). Functions support parameters, which can be used within the functions themselves. For example:

game.Players.PlayerAdded:Connect(function(player)
end)

The player in the last bracket will let us refer to the player’s instance in the game when necessary. You should try learning the basic concepts of how things work before diving into intermediate projects such as this; not that there is anything wrong with it but you will just find yourself struggling a lot and asking for help. We (me or others) won’t provide you with code just like that, because you won’t learn; here is a basic example of how the method GetNameFromUserIdAsync() can work. Make sure to read the comments on the code:

local Players = game:GetService("Players") --Defines 'Players', now we can use 'Players' freely in our code to refer to the service.

Players.PlayerAdded:Connect(function(player) --Detects when a player joins, the 'player' in the brackets like mentioned above refers to the player who joined.
    print(player.Name) --Prints the player's name.
    local ID = Players:GetUserIdFromNameAsync(player) --Gets the ID of the player. You can use 'player.UserId' but I am just giving you an example as you will need it for your game that involves getting their IDs from DataStores. If we use 'ID' anywhere else within this function, it will refer to the player's ID.
    local Name = Players:GetNameFromUserIdAsync(ID) --Get the player's name using this method. Useful if you want to print out names from IDs in your DataStore.
end)

So in your case, name = players:GetNameFromUserId(id) is not only attempting to grab a name of an undefined instance but it is also an invalid method. Capitlisation and spacing matters when it comes to (any type of) programming, so make sure to keep that in mind.

Anyway didn’t meant to sound harsh in this response, just wanted to share with you how you should try to do things because I once struggled with this too haha! :smiley:

1 Like