Firebase事务() - 添加到列表时的功能类似?

Mat*_*son 4 firebase

这是一个相当复杂的问题,但我会尽可能简单而简洁地解释它......

我正在使用Firebase构建一个基于Web的多用户游戏.我保留了游戏中每一轮的清单.在一轮结束时,每个用户都会看到一个"开始"按钮,当他们准备开始下一轮时,他们会点击该按钮.当至少50%的用户点击"开始"时,该轮开始.

我有一个gameRef游戏的Firebase参考,一个roundListRef代表轮次列表的参考,以及一个roundRef代表当前轮次的参考.

我附加了一个child_added回调,roundListRef以便在添加新回合时,它成为每个人的当前回合:

roundListRef.on('child_added', function(childSnapshot, prevChildName) {
    roundRef = childSnapshot.ref();
});
Run Code Online (Sandbox Code Playgroud)

我可以跟踪newRoundVotesactivePlayers,并从那里很容易计算出50%.如果达到50%,则会添加新一轮,触发每个人的child_added事件,新一轮将从那里开始......

gameRef.child('newRoundVotes').on('value', function(snapshot) {
    var newRoundVotes = snapshot.val();

    gameRef.child('activePlayers').once('value', function(snapshot) {
        var activePlayers = snapshot.val();

        if (newDriveVotes / activePlayers >= 0.5)
            addNewRound();
    });
});
Run Code Online (Sandbox Code Playgroud)

我的问题是,我如何确保只添加一轮新轮次,并且每个人都在同一轮?

例如,假设有10名球员,4名已经投票开始下一轮比赛.如果第6名玩家child_added在第5名玩家触发事件之前投票,那么第6名玩家也将加入一轮.

问题类似于.set()vs .transaction(),但不完全相同(根据我的理解).

有没有人有办法解决吗?

Mic*_*uer 6

如果提前知道圆形名称,我认为你可以通过交易来解决这个问题.例如,如果您只使用/ round/0,/ round/1,/ round/2等.

然后你可以有一些代码,如:

function addNewRound() {
    var currentRound = Number(roundRef.name());
    var nextRound = currentRound + 1;

    // Use a transaction to try to create the next round.
    roundRefList.child(nextRound).transaction(function(newRoundValue) {
        if (newRoundValue == null) {
            // create new round.
            return { /* whatever should be stored for the round. */ };
        } else {
            // somebody else already created it.  Do nothing.
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

这适用于您的方案吗?