Hello Scripting Community!

I was recently working on a script that would give items based on a dictionary which contained the item and its game pass ID, or list of player ID's that would receive the item. Here is my script below:

ms = game:GetService("MarketplaceService")

BB = script["Big Boing"];
LGC = script["Low Gravity Crystal"];
HC = script["Helicopter Crystal"];
HotTea = script["Hot Tea"];
noclip = script.Noclip
heal = script.Heal

local developers = { --list of devs by player id
	98156531, --Me, JAG (TChilled)
	1339309430, --pineapples353
	1415880068 --TeasTown
}

local owner = {98156531} -- Me, JAG (TChilled)

local ItemList = {
	[heal] = owner,
	[noclip] = owner,
	[BB] = developers,
	[LGC] = 10734158,
	[HC] = 10749790,
	[HotTea] = 16334719
}
local OwnedItems = {}

--Gives tools to player
function RegisterItems(plr)
	print("Running Register Items")
	OwnedItems = {}
	for item, id in pairs(ItemList) do
		if tonumber(id) ~= nil then
			local hasPass = ms:UserOwnsGamePassAsync(plr.UserId, id)
			if hasPass then
				local c = item:Clone()
				c.Parent = plr:WaitForChild("Backpack")
				OwnedItems[item] = true
				print(c.Parent)
				print(item, OwnedItems[item])
			else
				OwnedItems[item] = false
				print(item, OwnedItems[item])
			end
		else
			for i, v in pairs(id) do
				if plr.UserId == v then
					local c = item:Clone()
					c.Parent = plr:WaitForChild("Backpack")
					OwnedItems[item.Name] = true
					print(c.Parent, c, item) -- Prints Backpack, the item (Ex: Noclip), and the item from the list (Again, noclip)
					print(item, OwnedItems[item.Name]) -- Prints the item (Noclip) and true
					break
				else
					OwnedItems[item.Name] = false
					print(item, OwnedItems[item.Name])
				end
			end
		end
	end
	
	local folder = Instance.new("Folder", script)
	folder.Name = plr.Name
	for item, owned in pairs(OwnedItems) do
		if owned == true then
			local val = Instance.new("BoolValue", folder)
			val.Name = item
			val.Value = true
		end
	end
	game.ReplicatedStorage.ItemStatusUpdated:FireClient(plr, OwnedItems)
end

--Update tools based on true/false values for them
function UpdateItems(plr) --Only prints on player reset
	print("Running Update Items")
	local plrTools = script:FindFirstChild(plr.Name)
	if plrTools then
		plr:WaitForChild("Backpack"):ClearAllChildren()
		for i, v in pairs(plrTools:GetChildren()) do
			if v.Value == true then
				print(v) -- prints the item (Ex: Noclip)
				print(not plr:WaitForChild("Backpack"):FindFirstChild(v.Name)) -- prints true
				if not plr:WaitForChild("Backpack"):FindFirstChild(v.Name) then
					local item = plrTools:FindFirstChild(v.Name)
					local c = item:Clone()
					c.Parent = plr:WaitForChild("Backpack")
					print(c.Parent) -- prints Backpack
				end
			end
		end
	end
end

game.Players.PlayerAdded:Connect(function(plr)
	RegisterItems(plr)
	plr.CharacterAdded:Connect(function()
		UpdateItems(plr)
	end)
end)

game.ReplicatedStorage.ItemStatusUpdated.OnServerEvent:Connect(function(plr,item)
	OwnedItems = script:FindFirstChild(plr.Name):GetChildren()
	for i, v in pairs(OwnedItems) do
		if v.Name == item then
			v.Value = not v.Value
		end
	end
end)

game.ReplicatedStorage.RequestToolStatus.OnServerInvoke = function(plr)
	local EnabledItems = {}
	OwnedItems = script:FindFirstChild(plr.Name):GetChildren()
	for i, v in pairs(OwnedItems) do
		EnabledItems[v.Name] = v.Value
	end
	return EnabledItems
end

When ran, it is sort of random on how the items are given. Sometimes they are given in a different order, but 90 percent of the time, most if not all are not given whatsoever, although the print values remain the same every test. While I have figured out how to fix the issue with the UpdateItems function (It gives the BoolValues, not the items), I can't seem to figure out why the RegisterItems function is not giving the player the items here, because as I've said before, they give some or none of the items (And when checked in the backpack of the client and the server, it is no different than what was displayed as given to the client.).

Any help is appreciated :)