简体   繁体   English

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

[英]how do I loop through this database and get the child values?

I have this database, which looks like this 我有这个数据库,看起来像这样 在此输入图像描述

so the first keys are user uid taken from auth, and then the username he/she provided and what did they score for each match are taken also.. 所以第一个键是用户uid取自auth,然后他/她提供的用户名以及他们为每场比赛得分的内容也被采取..

I just wanted to get each user total points - for example Ray total points is 45 and Wood total points is 44 but after looking through for the docs all I was able to do was just for one user, I have to write each user name and the specific match for each line to get the value.. now think of how it will be if they are dozens of users? 我只是希望得到每个用户的总分 - 例如Ray总分为45分,而Wood总分为44分,但在查看了文档之后,我能够做的只是一个用户,我必须编写每个用户名和每条线的具体匹配得到的价值..现在想想如果他们是几十个用户会是怎样的? hmm a lot of lines.. 嗯很多线..

here is the JSON 这是JSON

the javascript code 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);
  });
 })

which will let me display, Ray total points, but not for Wood obviously I have to repeat it and write it.. 这将让我显示,雷总分,但不是伍德显然我必须重复它并写它..

So how do i solve this? 那么我该如何解决这个问题呢?

simply add total node to your db 只需将节点添加到您的数据库

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

and then get user`s total 然后得到用户的总数

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

you can add the total node using cloud functions 您可以使用云功能添加总节点

I took a look at your problem and I think I have your solution, or at the very least a PATHWAY to your solution. 我看了你的问题,我认为我有你的解决方案,或者至少是你解决方案的途径。 Ok, first I'll explain the basic issue, then I'll attempt to provide you with some generic-ish code (I'll attempt to use some of the variables you used). 好的,首先我将解释基本问题,然后我将尝试为您提供一些泛型代码(我将尝试使用您使用的一些变量)。 And away we go! 我们走吧!

Basically what I see is 2 steps... 基本上我看到的是两步......

STEP 1 - You need to use a "constructor function" that will create new user objects with their own name (and/or user ID) and their own set of properties. 第1步 - 您需要使用“构造函数”,它将创建具有自己的名称(和/或用户ID)以及它们自己的属性集的新用户对象。

With that line of thinking, you can have the constructor function include properties such as "user name", "match points 1", "match points 2" and then a function that console logs the summary of each name and their total points from match points 1 and 2. 通过这种思路,您可以使构造函数包含诸如“用户名”,“匹配点1”,“匹配点2”之类的属性,然后是控制台记录每个名称的摘要及其匹配总点数的函数第1点和第2点。

STEP 2 - You need to put the constructor function inside of a loop that will go through the database looking for the specific properties you need to fill in the properties needed by the constructor function to spit out the info you're looking for. 第2步 - 您需要将构造函数放在一个循环中,该循环将通过数据库查找您需要填充构造函数所需的属性以吐出您正在寻找的信息所需的特定属性。

So... and let's take a deep breath because that was a lot of words... let's try to code that. 所以...让我们深呼吸,因为这是很多话......让我们尝试编码。 I'll use generic properties in a way that I think will make it easy for you to insert your own property/variable names. 我会以一种我认为可以让您轻松插入自己的属性/变量名称的方式使用泛型属性。

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.");};
}

the "This" part of the code allows ANY user name to be used and not just specific ones. 代码的“This”部分允许使用任何用户名,而不仅仅是特定的用户名。

Ok, so the code above takes care of the constructor function part of the issue. 好的,所以上面的代码处理问题的构造函数部分。 Now it doesn't matter how many users you need to create with unique names. 现在,您需要使用唯一名称创建多少用户并不重要。

The next step is to create some kind of loop function that will go through the database and fill in the properties needed to create each user so that you can get the total points from EVERY user and not just one. 下一步是创建某种循环函数,该函数将遍历数据库并填写创建每个用户所需的属性,以便您可以从每个用户而不是一个用户获得总分。

Again, I will use generic-ish property/variable names... 再次,我将使用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.");};
    }
}

That is a whole lot of words and the code is a hybrid of generic property names/variables and of property names/variables used by you, but I'm certain that I am on the correct pathway. 这是很多单词,代码是通用属性名称/变量和您使用的属性名称/变量的混合,但我确信我在正确的路径上。

I have a lot of confidence that if you used the code and EXPLANATION that I provided, that if you plug in your own variables you will get the solution that you need. 我非常有信心,如果您使用我提供的代码和EXPLANATION,如果您插入自己的变量,您将获得所需的解决方案。

In closing I just want to say that I REALLY hope that helps and if it doesn't I'd like to help solve the problem one way or another because I need the practice. 最后,我只是想说,我真的希望有所帮助,如果不是,我想以这种或那种方式帮助解决问题,因为我需要这种做法。 I work a job with weird hours and so if I don't answer right away I am likely at my job :( 我工作很奇怪,所以如果我不立即回答,我很可能在工作:(

Good luck and I hope I helped! 祝你好运,我希望我帮助过!

Check out this implementation. 看看这个实现。 No need for cloud function. 不需要云功能。

 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);                         
   });    

  });
 })

If the key is the user's Id, why add yet another nested object with the user's name? 如果密钥是用户的Id,为什么要添加另一个具有用户名称的嵌套对象? Do you expect one user to have multiple usernames? 您希望一个用户拥有多个用户名吗? That sounds weird and adds on complexity, as you have probably noticed. 这听起来很奇怪,增加了复杂性,正如你可能已经注意到的那样。 If you need to keep the user name somewhere in Firebase, it is recommended that you dedicate a user details section somewhere directly under the user Id key. 如果您需要在Firebase中的某个位置保留用户名,建议您直接在用户ID键下的某个位置专用用户详细信息部分。 Here is a JavaScript representation of the Firebase object structure: 以下是Firebase对象结构的JavaScript表示:

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

Now, getting to the total points seems a bit more straightforward, does it not? 现在,达到总积分似乎更直接,不是吗? 😎 😎

To help you without modifying your current database structure, all you need is to loop through all the userId+username+matches permutation in your database. 为了帮助您而不修改当前的数据库结构,您只需循环遍历数据库中的所有userId +用户名+匹配排列。 Here is an example code to achieve just that, you do not need any special Firebase feature, just good old JavaScript for-of loop: 下面是一个实现这一目的的示例代码,您不需要任何特殊的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
      }
    }
  }
})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM