Why are messages being sent to everyone, even with friend checks in place?

When a player sends a message, I invoke a RemoteFunction, and this in the function that goes on the server.

Basically, I do all the necessary checks, make sure the player is friends with who they are sending to, filter the message, set a character cap, etc. However, for some reason, some messages get sent to everyone. I will join and have 4-5 messages from random strangers. I’m unsure how they are getting these messages through to me, and they dont seem like they are exploiting, as the prints return valid responses.

For example, this print

print(player.Name .. " has successfully sent a message to: " .. sendingTo)

returns
“Laurynbunny1 has successfully sent a message to: omiannic”

Which when I look, said player is friends with that player. However, I ended up getting the message saved to my data too, and other people have reported getting messages.

When I do Get and Set for the data stores, I pass through the players ID and so it 100% is only getting their messages. I don’t know how it’s getting my ID or other peoples ID’s though. As I’ll be completely offline, and return back and have these messages saved to my account. So it’s not getting my player in game at all, but somehow miraculously getting other players ID’s without them even being in game

local function MessageSent(player, sendingTo, message)
	-- Get player sending to
	local RecipientID
	
	local Success, Error = pcall(function()
		RecipientID = Players:GetUserIdFromNameAsync(sendingTo)
	end)
	
	if not Success then return 'Player does not exist' end
	
	if not RecipientID then return 'Error' end
	
	-- Make sure player is friends with RecipientID (can only send messages to friends)
	if not player:IsFriendsWith(RecipientID) then return 'Not friends' end
	
	local FilteredMessage = Chat:FilterStringForBroadcast(message, player)
	
	if string.len(FilteredMessage) > 150 then return 'Error' end
	
	local Data = GetData(RecipientID)
	
	-- Check if Data exists
	if not Data then return end
	
	if #Data.Messages >= 5 then return 'Inbox full!' end -- User has too many messages (from 10 different users)
	
	local FoundUser = false
	print("Message data", RecipientID)
	for i, v in pairs(Data.Messages) do
		if i == player.Name then -- Already got a message from that player
			if #v >= 5 then -- Check to make sure they don't have a ton of messages from same player
				return 'Inbox full!'
			else -- All good, send the message
				table.insert(Data.Messages[i], FilteredMessage)
				FoundUser = true
				
				break
			end
		end
	end
	print(player.Name .. " has successfully sent a message to: " .. sendingTo)
	if not FoundUser then
		print("Adding", player.Name, "to list")
		Data.Messages[player.Name] = {FilteredMessage}
	end
	
	TaskManager.Complete(player, "Messenger") -- Complete task
	
	local TryCount = 0
	
	local Success, Error
	
	-- Save data
	repeat
		Success, Error = pcall(function()
			DataStore:SetAsync(RecipientID, Data)
		end)
		
		TryCount += 1
	until TryCount >= Tries or Success
	print("Saving message to", RecipientID, Success)
	-- Failed to save
	if not Success then
		warn('Data failed to save | Error Code:' .. tostring(Error))
		
		return 'Error'
	else -- Data saved successfully
		MessagingService:PublishAsync(
			'Messages',
			{
				Message = FilteredMessage,
				Sending = player.Name,
				Recipient = sendingTo
			}
		)
		
		return 'Sent!'
	end
end

Please note, this is the ONLY code in the game that alters the players data store for messages.

Looks like each recipient has a shared inbox. Anyone who can send to a user can see every message that’s been sent to that user.

I’d recommend both having a recipient inbox, and a sender outbox. Use the sender outbox for displaying messages you have sent to others, and use the recipient inbox for displaying messages that you (not someone else) got from others.