Save your player data with ProfileService! (DataStore Module)

You may use the return value of ProfileStore:ViewProfileAsync(). It will return nil if no profile is linked to the provided key.

1 Like

I’m new to ProfileService and am having an issue with some of my profile data. I have the following template:

local ProfileTemplate = {
	BestRaceTimes = {}, -- [courseNumber] = elapsedTime
	RaceCounts = {}, -- [courseNumber] = raceCount
	LogInTimes = 0,
}

This data is being updated in two ways. The first way works fine:

local function UpdateProfileLogInTimes(player, profile)
	profile.Data.LogInTimes += 1
	print(player.Name .. " has logged in " .. tostring(profile.Data.LogInTimes)
		.. " time" .. ((profile.Data.LogInTimes > 1) and "s" or ""))
end

The second way updates profile.Data but the changes aren’t getting saved to the Datastore:

local function updateRaceData(player, courseNumber, elapsedTime)
	print("PlayerProfile updateRaceData", player.UserId, courseNumber, elapsedTime)
	local profile = PlayerProfiles[player].Profile
	local bestTime = profile.Data.BestRaceTimes[courseNumber]
	if bestTime == nil or elapsedTime < bestTime then
		profile.Data.BestRaceTimes[courseNumber] = elapsedTime
	end
	if profile.Data.RaceCounts[courseNumber] == nil then
		profile.Data.RaceCounts[courseNumber] = 0
	end
	profile.Data.RaceCounts[courseNumber] += 1
end

SavepointRemoteEvent.OnServerEvent:Connect(updateRaceData)

Any idea what I am missing or doing wrong?

Hello. I have a quick question.

Is there anyway I am able to read / extract data from a profile in profile service without having to load it normally. I am also wondering how I would be able to access ALL profile entries in my profile data store.

Any help would be appreciated.

On the 3rd line, local profile = PlayerProfiles[player].Profile
I don’t think the .Profile is necessary. So you should just be able to access the data by PlayerProfiles[player].Data instead of PlayerProfiles[player].Profile.Data

Wow! A person from a discord server recommended me this, and I am very thankful because this helped a lot! Thanks, @breadbutcooler !

3 Likes

Actually, I need .Profile because I’m also using ReplicaService so my PlayerProfiles looks like this:

local PlayerProfiles = {} -- [player] = {Profile = profile, Replica = replica}

Learning this module was worth my time, thanks for providing this loleris :slight_smile:

1 Like

Anybody struggling with using :Reconcile()?

Been using this module for over a year and haven’t had any issues. Now however I’m finding it impossible to remove old data values. Using :Reconcile() on the profile usually fixed this, however now it seems to do nothing. Anybody having similar experiences with possible solutions?

:Reconcile() doesn’t remove existing data from a player’s profile; it only fills in variables from the current ProfileTemplate that the player doesn’t have in their profile already.

If there are any existing variables in a player’s profile that you want to remove, that would need to be done separately.

1 Like

How trust worthy is whats preventing multiple server editing? In my case, players can like a players creation from other servers meaning there could be a lot of data trying to overlap.

ProfileService session-locking is more for avoiding players from having two servers with ‘active’ session data by attaching a job-id to the session when the player is in a server. If you try to load another profile with this session data active, the player will have to wait a bit for the data to become available, as the new server requests to take over by appending a force request, wait a bit, if the session was released, the new server takes it back, if the session didn’t release, it’ll assume the session died and take over.
ProfileService forces only one server to have an active attachment of a profile if you have Loaded their profile.

TL;DR. It’s best to use ProfileService for making sure only one session has access to an ID at a time.

As for wanting to add a like to another players creation, you could instead use DataStore directly and use UpdateAsync which makes all other servers get into a ‘queue’ to update the data if multiple servers are wanting to add a like.

UpdateAsync(“key”,function(current key)
current key[ likes ] = current key[ likes ] + 1
return current key
end) )

Roblox does the work to make sure other servers who also want to add an update, yeild, until the previous one has returned data.

https://developer.roblox.com/en-us/api-reference/function/GlobalDataStore/UpdateAsync

GlobalDataStore:UpdateAsync is safer for handling multi-server attempts because it reads the current key value (from whatever server last updated it) before making any changes. However, it’s somewhat slower because it reads before it writes, and it also counts against both the read and write limit.

1 Like

I never knew default datastore did this, thank you!

How often does profile service check to see if a player’s session is still locked?

How does profile service handle when a session is locked on a live server and someone is trying to login from a second?

For the second question, it will depend on what you put for the second variable.

  • ForceLoad - Will repeatedly request the server that has it locked to release it or will steal it after a certain amount of attempts.

  • Steal - Ignores session lock

Refer to the not_released_handler for the ones below.

  • Repeat - Will continuously attempt to load the profile (Profile locks automatically timeout after 30 minutes if server holding it has crashed)

  • Cancel - Cancels the load attempt and returns nil for the profile

https://madstudioroblox.github.io/ProfileService/api/#profilestoreloadprofileasync

Great! Okay that helps.

Is there a method for immediately forcing a save through the queue?
For instance, if you have a transaction between two players and you want to ensure they are both saved even if one instantly logs off (queueing a save) and then the server explodes preventing the service from saving the player.

If not, how does profile service handle this edge case?

Profile:Save()

It is explicitely mentioned to not use this method to save profile.Data

image

when you use the function ProfileStore:WipeProfileAsync(ProfileKey) and the wipe is successful
then your profile will only have the key GlobalUpdates inside which is normal.

but then when ProfileService autosaves the profiles and it attempts to save that one profile that wiped
it will error in lines like local active_session = latest_data.MetaData.ActiveSession which has no checks if the latest_data.MetaData exists

all this only applies if the player is in-game and his profile is loaded ofc

Changing Data doesnt work for me. I Did Profile.Data.Value = “randomstringexample” and when i print profile it still shows the original template not “randomstringexample”

Should Profile Service Handle (Data Store Was added To The queue ,further requests will be dropped, etc…) error ?
I Use Profile Service and got This error
Cuz I use Profile Service To avoid This error and related errors