I am currently developing a 1 vs 1 game matching system using a real-time database. The system works by creating a record in the users table when a user signs in. Once there are two players with a status of placeholder, a cloud function generates a gameInfo for these players and changes their status to waiting. To achieve this, I have implemented a trigger function that observes the status of users/{uid}. When the status is placeholder, the matchmaker function is called to generate a unique gameId for the two players. However, I've encountered an issue where sometimes, due to quick database changes, the trigger function runs twice before the database has fully updated. This results in two unique gameId records being generated instead of one. I'm looking for a solution to prevent this unexpected behavior. Here is a snapshot of the database table: https://i.sstatic.net/oNU59.png
Below is a portion of my cloud function code. The searchWaitingPlayers function checks for two players in the waitingPlayers map and generates a gameId record in the games table.
export const searchWaitingPlayers = functions.database.ref("users/{uid}").onWrite( (change, context) => {
if (!change.after.exists()) {
console.log("uid deleted");
return null;
} else {
if (change.after.child("status").val() !== "placeholder") {
console.log("user's status is not placeholder");
waitingPlayers.delete(change.after.key);
} else {
waitingPlayers.clear();
admin.database().ref("users").once("value").then(async (users) => {
users.forEach((user) => {
if (user.child("status").val() === "placeholder") {
waitingPlayers.set(user.key, user.child("username").val());
}
});
matchmaker();
});
}
return null;
}
});