Profile service returning nil

Hi. When the first player joins within my game, the script is functional and loads data. However anyone else who joins after, the get method will simply return nil.
Script that deserialises data into a folder parented to player:

game.Players.PlayerAdded:Connect(function(p)
    repeat task.wait() until DataManagerScript.Loaded.Value

    local data = DataManager:Get(p)
    if data.clan == "UNDEFINED" then -- attempt to index data.clan
        local newClan = rerollEvent:Invoke()

        data.clan = newClan
    end

    local folder = Instance.new("Folder")
    folder.Name = "Data"
    folder.Parent = p

    for key, value in pairs(data) do
        if instanceValues[typeof(value)] then
            local valueInstance = Instance.new(instanceValues[typeof(value)])
            valueInstance.Name = key
            valueInstance.Value = value
            valueInstance.Parent = folder
            valueInstance.Changed:Connect(function(val)
                data[key] = val
            end)

        end
    end
end)

DataManager module:

local Players = game:GetService("Players")
local ProfileService = require(game.ServerScriptService.ProfileService)

local template = 	{
	forms = {},
	style = "basic",
	cash = 500,
	strength = 0,
	durability = 0,
	clan = "UNDEFINED",
	name = "UNDEFINED",
	clanRerolls = 5,
	gender = false,
	firstTime = true,
	authority = 0,
	bans = 0,
	warns = 0,
	currentState = "Unmoderated",
	lastWarn = 0,
	lastBan = 0,
	banDuration = 0,
	customClan = ""
}

local ProfileStore = ProfileService.GetProfileStore(
	"Player",
	template
)

local Profiles = {}


local function onPlayerAdded(player)
	local profile = ProfileStore:LoadProfileAsync(
		"Player_" .. player.UserId,
		"ForceLoad"
	)
	
	if profile then
		
		
		profile:ListenToRelease(function()
			Profiles[player] = nil
			player:Kick("Session Lock Released.")
		end)
		
		if player:IsDescendantOf(Players) then --// Check if player is still within the game
			Profiles[player] = profile
			
			for i,v in pairs(profile.Data) do
				if template[i] == nil then
					profile.Data[i] = nil
				end
			end
			
			for i,v in pairs(template) do
				if profile.Data[i] == nil then
					profile.Data[i] = v
				end
			end
			
			warn("--PROFILE LOADED--")
			
			if not script.Loaded.Value then
				script.Loaded.Value = true
			end
			
		else
			profile:Release() --// If not, then release session lock
		end
	else
		player:Kick("There was an error loading player data.")
	end
end

local function onPlayerRemoving(player) --// when the player leaves, release the session lock on their profile
	local profile = Profiles[player]
	if profile then
		profile:Release()
	end
end

Players.PlayerAdded:Connect(onPlayerAdded)
Players.PlayerRemoving:Connect(onPlayerRemoving)


local DataManager = {}

function DataManager:Get(player)
	local profile = Profiles[player]
	
	
	if profile then
		return profile.Data
	end
	
end

return DataManager
2 Likes

Probably because you’re connecting both the onPlayerAdded function and the deserialization at the same time. When a player joins the game, the event would fire both of thee functions, and lets say the deserialization script runs first before the onPlayerAdded function, and then inside the deserialization script you called the Get method, and it returns nil because the onPlayerAdded function didn’t manage to get the profile for the player first.

The solution here is just combine both of these function.

2 Likes

Using your advice I managed to get it working by combining the deserialisation part and the onPlayerAdded event within the datamanager. Thanks!

1 Like