Проблемы онлайн-поиска в облачной функции и базе данных в реальном времени - PullRequest
0 голосов
/ 05 августа 2020

Облачная функция настроена на запуск при создании новой записи и проверяет, достаточно ли у нас игроков, чтобы начать игру. Если это так, он создает игру по адресу ‍‍ /matches и записывает gameId в запись каждого игрока, например: /users/{playerId}/profile/cm

Игроки слушают gameId в своих записях базы данных, поэтому они знать, когда перейти к экрану GamePlay.

Поскольку много игроков одновременно запрашивают поиск противника, а облачная функция - это асинхронный параллелизм, возникают проблемы с параллелизмом, и, как вы можете видеть на картинке, пользователь добавлен в двух разных совпадениях.

Firebase realtime database image enter image description here

const functions = require('firebase-functions');

const admin = require('firebase-admin');
admin.initializeApp();

exports.onNewRequest = functions.database.ref("/requests/{boardId}/{userId}").onCreate((change, context) => {
    var boardId = context.params.boardId;
    var createdUserId = context.params.boardId;
    // new request created
    var requests = admin.database().ref("/requests/"+boardId);
    requests.once("value").then((requestsSnapshot)=>{
        var waitersCount = requestsSnapshot.numChildren();
        if(waitersCount > 1){
            // more than one user waiting to join the game
            // lets link users
            var creatorSnapshot;
            var guestSnapshot;
            // more than two players waiting to play a game on the board{boardId}
            var index = 0;
            requestsSnapshot.forEach((childSnapshot) => {
                if (index === 0) creatorSnapshot = childSnapshot;    
                if (index === 1) guestSnapshot   = childSnapshot;
                index++;
            });

            // we have the creator and the guest
            // creatorSnapshot.key is the id of the user /requests/boardId/userId <<<<--
            var match = admin.database().ref("/matches").push({
                s: 1,
                peers:{
                    [creatorSnapshot.key]:true,
                    [guestSnapshot.key]:true
                }
            });
            match.then(()=>{
                // delete waiters

                admin.database().ref("/users/"+creatorSnapshot.key+"/profile/cm").set(match.key);
                admin.database().ref("/users/"+guestSnapshot.key+"/profile/cm").set(match.key);
                
                creatorSnapshot.ref.remove();
                guestSnapshot.ref.remove();

                return null;
            }).catch((error) => {
                console.log(error);
            });
            // var matchId = boardId + "-" + creatorSnapshot.key + "-" + guestSnapshot.key;
            // return admin.database().ref("/matches/"+matchId).set({
            //     s: 1,
            //     peers:{
            //         [creatorSnapshot.key]:true,
            //         [guestSnapshot.key]:true
            //     }
            // }).then(()=>{
            //     // delete waiters
            //     // creatorSnapshot.ref.remove();
            //     // guestSnapshot.ref.remove();
            //     return null;
            // }).catch((error) => {
            //     console.log(error);
            // });
        }
        return null;
    }).catch((error) => {
        console.log(error);
    });
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...