I have implemented a cloud function for firebase that takes care of matchmaking. It works like that: if a player looks for a game, my function first checks if there are any open games(another user looking for a game) if there is such a game, I update the game by saying it's a closed game. if no open game has been found, I create a new open game. with this implementation I have the following question: let's assume player A created an open game and now Player B and Player C are looking for a game at the same time. How can I avoid that both of them getting assigned to player A open Game. So basically I only want ONE of them assigned.
EDIT:
I save my games in firestore and i have a property called player2 which is set to -1 if there is no player2 yet. my implementation looks like this:
exports.findGame = functions.https.onCall(async (data, context) => {
//get game with no player2
const gameWithoutPlayer2 = await admin.
firestore()
.collection('games')
.where("player2", "==", "-1")
.limit(1)
.get();
//check if a game without player2 exist
if (gameWithoutPlayer2.docs[0] == null) {
//no game found => create new one
await createNewGame(context.auth.uid);
} else {
//game found => we are player2
//get name of player:
const player2Result = await admin.firestore().collection('users').doc(context.auth.uid).get();
await admin.firestore().collection('games').doc(gameWithoutPlayer2.docs[0].id).update({ player2: context.auth.uid, player2Name: player2Result.data().Username });
}
})
I would suggest using Firestore Realtime Database (at least for the matchmaking part in the waiting room) and also taking a look into transactions, which will ensure that no one has created or joined a game while we are attempting to do it via atomic operations.
I have found here an implementation on Java using Firestore Realtime Database and Transactions that could be useful to you.