简体   繁体   中英

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..

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? hmm a lot of lines..

here is the JSON

the javascript code

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.

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.

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.

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.

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...

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.

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? 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. Here is a JavaScript representation of the Firebase object structure:

{
  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. Here is an example code to achieve just that, you do not need any special Firebase feature, just good old JavaScript for-of loop:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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