提问者:小点点

Nodejs Firebase事务-更新节点


场景是当玩家点击应用程序中的“加入游戏”时,调用云函数将玩家添加到firebase数据库,结果作为响应传递。

数据库结构:

/games
|--/game_id
|----/players => this is a json array of uids and their status([{"uid1": true}, {"uid2":true},...])
|----/max_players = 10

cloud函数应该检查/players的大小是否小于/max_players,只有这样,它才应该用播放器的uid更新/players并返回响应。

下面是我的云功能:

export const addUserToGame = functions.https.onCall((data, context) => {

    // Expected inputs - game_id(from data) and UID(from context)

    if (context.auth == null) {
        return {
            "status": 403,
            "message": "You are not authorized to access this feature"
        };
    }

    const uid = context.auth.uid;
    const game_id = data.game_id;

    let gameIDRef = gamesRef.child(game_id);

    return gameIDRef.transaction(function (t) {

        if (t === null) {
            return {
                "status": 403,
                "message": "No game found with id"
            };
        } else {

            let playersNode;
            let isAlreadyPlayer = false;
            if (t.players) { // is this the correct way to access the /players in the /game_id node?
                console.log("players is not empty");

                playersNode = t.players;
                let players_count = playersNode.length;
                let max_players: Number = t.max_players;

                if (players_count >= max_players) {
                    return {
                        "status": 403,
                        "message": "Max players reached"
                    };
                }

                for (var i = 0; i < playersNode.length; i++) {
                    if (playersNode[i].uid === uid) {
                        isAlreadyPlayer = true;
                    }
                    break;
                }

                if (!isAlreadyPlayer) {
                    playersNode.push({
                        [uid]: "active"
                    });
                }
              
                return t.players.update(JSON.stringify(playersNode));

            } else {
                playersNode = [];
                playersNode.push({
                    [uid]: "active"
                });

                t.players = JSON.stringify(playersNode);
                return t;
            }

        }

    },function(error, committed, snapshot) {

        if(committed) {
            return {
                "status": 200,
                "message": "Player added successfully"
            };
        } else {
            return {
                "status": 403,
                "message": "Error adding player to the game"
            };
        }

    });

});


云函数崩溃,错误如下:

TypeError: Cannot read property 'update' of undefined
    at Object.gameIDRef.transaction.status [as update] (/workspace/lib/game.js:134:30)
    at Repo.rerunTransactionQueue_ (/workspace/node_modules/@firebase/database/dist/index.node.cjs.js:14647:40)
    at Repo.rerunTransactions_ (/workspace/node_modules/@firebase/database/dist/index.node.cjs.js:14600:10) 

错误指向第134行,它是

  if (players_count >= max_players) {
                    return { // line 134
                        "status": 403,
                        "message": "Max players reached"
                    };
                }

我到底做错了什么?

编辑1:

我更改了if/else条件中的return语句。 值现在得到更新,但函数以代码500完成。


共1个答案

匿名用户

您正在尝试访问未定义变量的函数属性。 在本例中,T没有属性Players(您已经在上面的if语句中检查了该属性)。 但是,在if语句之外,您仍然在访问t.players.update,并且由于t.players未定义,因此会出现错误