如何遍历此数据库并获取子值?

时间:2017-06-10 14:55:26

标签: javascript firebase firebase-realtime-database

我有这个数据库,看起来像这样 enter image description here

所以第一个键是用户uid取自auth,然后他/她提供的用户名以及他们为每场比赛得分的内容也被拍摄..

我只想让每个用户获得总分 - 例如 Ray 总分 45 Wood 总分 44 但在查看文档之后,我能够做的只是一个用户,我必须编写每个用户名和每行的特定匹配来获取值..现在想想它将如何如果他们是几十个用户?嗯很多行..

这是JSON

javascript代码

var query = firebase.database().ref();
 query.once("value")
 .then(function(snapshot) {
 snapshot.forEach(function(childSnapshot) {

  var key = childSnapshot.key;      
  var Data1 = childSnapshot.child("Ray/Match1/Points").val();
  var Data2 = childSnapshot.child("Ray/Match2/Points").val();
  console.log(Data1 + Data2);
  });
 })

这将让我显示,雷总分,但不是伍德显然我必须重复它并写它..

那么我该如何解决这个问题?

4 个答案:

答案 0 :(得分:5)

只需将节点添加到您的数据库

即可
|_Id
   |_ $userId:
   |       |_ Ray
   |       |    |_ Match1:24
   |       |    |_ Match2:21
   |       |_ total:45

然后获得用户总数

var query = firebase.database().ref();
 query.once("value")
 .then(function(snapshot) {
 snapshot.forEach(function(childSnapshot) {
  var total = childSnapshot.child("total").val();
  console.log(total);
  });
 })

您可以使用cloud functions

添加总节点

答案 1 :(得分:5)

我看了你的问题,我认为我有你的解决方案,或者至少是你解决方案的途径。好的,首先我将解释基本问题,然后我将尝试为您提供一些泛型代码(我将尝试使用您使用的一些变量)。我们离开了!

基本上我看到的是两步......

第1步 - 您需要使用“构造函数”,它将创建具有自己的名称(和/或用户ID)及其自己的属性集的新用户对象。

通过这种思路,你可以让构造函数包含诸如“用户名”,“匹配点1”,“匹配点2”之类的属性,然后是控制台记录每个名称及其总数的摘要的函数来自赛点1和2的积分。

第2步 - 您需要将构造函数放在一个循环中,该循环将通过数据库查找您需要填充构造函数所需的属性的特定属性,以吐出您要查找的信息

所以...让我们深吸一口气,因为那是很多话......让我们试着编码。我将以一种我认为可以让您轻松插入自己的属性/变量名称的方式使用泛型属性。

var user = function(name, match1, match2){
    this.name = name;
    this.match1 = match1;
    this.match2 = match2;
    this.pointTotal = function(match1, match2) {
        console.log(match1 + match2);};
    this.summary = function(){
            console.log(name + " has a total of " + pointTotal + " 
points.");};
}

代码的“This”部分允许使用任何用户名,而不仅仅是特定用户名。

好的,所以上面的代码处理问题的构造函数部分。现在,您需要使用唯一名称创建多少用户并不重要。

下一步是创建某种循环函数,该函数将遍历数据库并填写创建每个用户所需的属性,以便您可以从每个用户获得总分,而不仅仅是一个。

同样,我将使用generic-ish属性/变量名......

var key = childSnapshot.key;

while(i = 0; i < key.length + 1; i++) {

    var user = function(name, match1, match2){
        this.name = name;
        this.match1 = match1;
        this.match2 = match2;
        this.pointTotal = function(match1, match2) {
            console.log(match1 + match2);};
        this.summary = function(){
            console.log(name + " has a total of " + pointTotal + " points.");};
    }
}

这是很多单词,代码是通用属性名称/变量和您使用的属性名称/变量的混合,但我确信我正在使用正确的路径。

我非常有信心,如果您使用我提供的代码和说明,如果您插入自己的变量,您将获得所需的解决方案。

最后我想说,我真的希望有所帮助,如果不是,我想以这种或那种方式帮助解决问题,因为我需要这种做法。我工作的时间很奇怪,所以如果我不马上回答,我很可能在工作:(

祝你好运,我希望我能帮到你!

答案 2 :(得分:2)

查看此实施。不需要云功能。

 firebase().database().ref().on('value', function(snapshot) {
 snapshot.forEach((user)=>{

  user.forEach((matches)=> {
     var total = 0;
     matches.forEach((match)=> {       
         total += match.val().Points;          
     }); 
     console.log(total);                         
   });    

  });
 })

答案 3 :(得分:1)

  

如果密钥是用户的ID,为什么还要添加另一个具有用户名称的嵌套对象?您希望一个用户拥有多个用户名吗?这听起来很奇怪,增加了复杂性,正如你可能已经注意到的那样。如果您需要在Firebase中的某个位置保留用户名,建议您直接在用户ID键下的某个位置专用用户详细信息部分。以下是Firebase对象结构的JavaScript表示形式:

{
  a1230scfkls1240: {
    userinfo: {
      username: 'Joe'
    },
    matches: {
      asflk12405: {
        points: 123
      },
      isdf534853: {
        points: 345
      }
    }
  }
}
  

现在,达到总积分似乎更直接,不是吗?

为了帮助您而不修改当前的数据库结构,您只需循环遍历数据库中的所有userId +用户名+匹配排列。下面是一个实现这一目的的示例代码,您不需要任何特殊的Firebase功能,只需要很好的旧JavaScript for循环:

const query = firebase.database().ref();

query.once('value')
.then(snapshot => {
  const points = {}
  const users = snapshot.val()

  for (const userId of Object.keys(users)) {
    const userprofile = users[userId]

    for (const username of Object.keys(userprofile)) {
      const user = userprofile[username]

      for (const matchId of Object.keys(user)) {
        const match = user[matchId]
        // Store the points per user, per profile, or per both, depending on your needs
        points[username] = points[username] === undefined
          ? points[username] = match.points
          : points[username] += match.points
      }
    }
  }
})