首页 > 解决方案 > 为什么我的数据在 Firebase 数据库中存储了两次?

问题描述

我是使用 Firebase 的新手,所以欢迎所有建议。

我想要达到什么目的?

只有当用户没有超过他们的团队规模(“numberOfplayersLimit”)时,我才想创建一个玩家。所以目前我正在使用一个firebase事务,它首先检查团队没有超过他们的限制“numberOfPlayers”,如果团队没有超过他们的限制,增加“numberOfplayersLimit”计数器,然后将玩家添加到数据库中,如下所示。

我的问题是什么

我目前正在使用.push()添加播放器,但是它创建了两次播放器,如下所示,因为您可以看到其他记录中的全名相同,但它们具有不同的 uid。

下面是我的 Firebase 实时数据库 JSON 结构的截图

在此处输入图像描述

var myUserId = firebase.auth().currentUser.uid;
    
const playerData = {
    fullName:this.state.fullName,
   
};

 //This is where the players are stored 
 const teamplayersref = firebase.database().ref('/teams').child(myUserId).child('/players')


 //Transaction - Team reference path for the TeamPlayers Limit
 const getTeamPlayersLimit = firebase.database().ref('/teams').child(myUserId).child('numberOfplayersLimit');

  getTeamPlayersLimit.transaction(function(numberOfplayersLimit){


        if (numberOfplayersLimit == 11) {
            alert('You have exceed your team size limit, Delete a player from your team or contact us to upgrade your package');
        }

        else 
        {
          
            //increment teamplayers limit
            numberOfplayersLimit = numberOfplayersLimit + 1;
              
 
            teamplayersref.push(playerData);
 
            return numberOfplayersLimit;

        }
    });

标签: javascriptfirebasereact-nativefirebase-realtime-database

解决方案


事务处理程序中的teamplayersref.push(playerData)调用不是事务本身的一部分。因此,如果重试事务,您最终会调用teamplayersref.push(playerData)多次,为每次尝试创建一个子节点。

要生成具有唯一推送 ID 的新子代,请使用不带参数的推送来获取新密钥,然后在return交易值中使用它。这意味着您的交易必须在整个firebase.database().ref('/teams')节点上运行,因为您正在修改计数器和玩家。

const teamRef = firebase.database().ref('/teams').child(myUserId);

teamRef.transaction(function(team){
    team = team || { numberOfplayersLimit: 0, players: {} };
    if (team.numberOfplayersLimit == 11) {
        console.error('You have exceed your team size limit, Delete a player from your team or contact us to upgrade your package');
    }
    else  {
        team.numberOfplayersLimit = team.numberOfplayersLimit + 1;
        const newPlayerKey = teamRef.push().key; // this line does not write to the database

        team.players[newPlayerKey] = playerData;

        return team;
    }
});

推荐阅读