DataStore can't be accessed from client

I’m making a developer product that teleports all players to a certain location when purchased.

(this is in a local script inside a TextButton that prompts the purchase.

local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")
local Gui = game:GetService('Players').LocalPlayer:WaitForChild('PlayerGui')
local Screen = Gui:WaitForChild("ScreenGui")
local Player = Players.LocalPlayer
DatastoreService = game:GetService("DataStoreService")

RecieptStorage = DatastoreService:GetDataStore("PurchaseHistory")

local productFunctions = {}

local ProductID = 1130296003

target = CFrame.new(14.9, 28.6, -5.3)

print(Players.LocalPlayer)

function promptPurchase() --prompts the purchase
	MarketplaceService:PromptProductPurchase(Player, ProductID)
end

Screen.TextButton.MouseButton1Click:Connect(promptPurchase)

productFunctions[1130296003] = function(receipt, player)
	if player.Character and player.Character:FindFirstChild("Humanoid") then
		for i, player in ipairs(game.Players:GetChildren()) do
			if player.Character and player.Character:FindFirstChild("HumanoidRootPart") then
				player.Character.HumanoidRootPart.CFrame = target + Vector3.new(0, i * 5, 0)
			end
		end
	end
end

When I run this, I get an error saying “DataStore can’t be accessed from client.”

I’m not sure what the issue is, if someone could help, that’d be great.

1 Like

You can only send calls to Data Stores from the server.
I suggest you use remote events or a module script with a ‘return’ function to use DataStoreService.

I"m sorry, but I’m not very good at scripting. How would I do this?

1 Like

Are you using DataStore:SetAsync() [adding info to the DS] or DataStore:GetAsync() [getting info from the DS]

I don’t even know what GetAsync is. :confused:

1 Like

just getting data from the data store
setting is just adding data to it

do you need to get the history or add something to the history?

Where in the script are you talking about?

1 Like

You can use these resources for any additional guidance

Also, yea, you can’t use data stores from the client because of exploits.

You have a datastore defined yet you aren’t actually using it within your script, try this, I just removed the datastore-related information.

local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")
local Gui = game:GetService('Players').LocalPlayer:WaitForChild('PlayerGui')
local Screen = Gui:WaitForChild("ScreenGui")
local Player = Players.LocalPlayer

local productFunctions = {}

local ProductID = 1130296003

target = CFrame.new(14.9, 28.6, -5.3)

print(Players.LocalPlayer)

function promptPurchase() --prompts the purchase
	MarketplaceService:PromptProductPurchase(Player, ProductID)
end

Screen.TextButton.MouseButton1Click:Connect(promptPurchase)

productFunctions[1130296003] = function(receipt, player)
	if player.Character and player.Character:FindFirstChild("Humanoid") then
		for i, player in ipairs(game.Players:GetChildren()) do
			if player.Character and player.Character:FindFirstChild("HumanoidRootPart") then
				player.Character.HumanoidRootPart.CFrame = target + Vector3.new(0, i * 5, 0)
			end
		end
	end
end

this section, it gets the data store, but is this going to be used to get information or is this script adding information?
ill type out a module script for both anyway

I put that in, the promptPurchase now works, but for some reason the teleporting thing isn’t working now?

You’re trying to teleport all players using a local script, reminder that local scripts effect the client only and won’t do actual change.

1 Like

So how do I fix this? I assume I have to use some remote Event or something like that.

In case you need to use it, as you defined a data store, here’s the way to do it from a client

In a module script:

local module = {}

--// Services
local DataStoreService = game:GetService("DataStoreService")

--// Variables
local RecieptStorage = DataStoreService:GetDataStore("PurchaseHistory")
local DataStoreKey = 'changeThisToSomethingRandom' -- changing this deletes all saved data

--// Functions [change value to whatever you're setting, player will be the user for the purchase history, product will be the product ID, etc.]
function module.SetAsync(player, product)
	local success, errormessage = pcall(function()
		RecieptStorage:SetAsync(player.UserId..product, product)
	end)
	
	if success then
		print("Successfully added data to data store!")
		return true
	else
		warn("Unable to add data to data store!")
		warn(errormessage)
		return false
	end
end

function module.GetAsync(player, product)
	local product = nil
	local success, errormessage = pcall(function()
		product = RecieptStorage:GetAsync(player.UserId..product)
	end)

	if success then
		print("Successfully got data from data store!")
		return product
	else
		warn("Unable to get data from data store!")
		warn(errormessage)
		return nil
	end
end

return module

In a local script:

local module = require(--[[ define your module here ]])

--to get data use this
local info = module.GetAsync(--[[the player, localPlayer is the local script's assigned player]] game.Players.LocalPlayer, --[[the product id]] 123456789)
if info then
	-- whatever it does with it
end

--to set data use this

module.SetAsync(--[[the player, localPlayer is the local script's assigned player]] game.Players.LocalPlayer, --[[the product id]] 123456789)

you can change the stuff within the module script to other stuff too, like other game services that can’t be called from the client

Yes, you have to use a remote event

-- localscript
local remote = -- remote event script directory

-- code inside script

remote:FireServer(...) -- replace "..." with whatever you want to send
-- server script
local remote = -- remote event here

remote.OnServerEvent:Connect(function(player, ...) -- the player who fired is passed automatically
       -- "..." would be your aguments
       
      -- code here
end)