0

When testing my code the console logs will be 2: 0 (multiple times), 3: 0 (once), 1: _ (multiple times where _ increases each time).

I am unsure as to how to get 1 to occur before 2 and 3 so that when I write to the database (after log 3) the value isn't 0.

I am unsure how to approach this problem as I am inexperienced with firebase.

  var count=0;
  var total=0;

  var ass_ref = admin.database().ref("modules/"+mod+"/Assignments");
  return ass_ref.once("value", function(snapshot) {

    snapshot.forEach(function(child) {

      var name = child.key;

      var ref = admin.database().ref("modules/"+mod+"/Assignments/"+name+"/"+uid);
      ref.once("value", function(mark) {

          count++;
          total=total+ parseInt(mark.val(),10);
          console.log("1:"+total);  //Value increases each time but occurs after 3

      });

      console.log("2:"+total);  //Value = 0 (occurs multiple times, in foreach)

    });

    console.log("3:"+total);  //Value = 0, logs once, after "2"

I desire 1 to occur before 2 (I believe it would log as 1,2,1,2...) so that the final value logged at 3 matches the last value logged at 1.

Papipone
  • 1,083
  • 3
  • 20
  • 39
Ryan
  • 1
  • I suggest learning how to work with promises to do asynchronous programming in JavaScript. `once()` returns a promise - learn how to use that. There is an introduction on using promises in Cloud Functions here: https://firebase.google.com/docs/functions/video-series – Doug Stevenson May 21 '19 at 15:43
  • @DougStevenson Thanks for the assistance, the videos proved helpful once I got a better understanding of promises. – Ryan May 21 '19 at 22:29

1 Answers1

0

Below is my working solution, it is probably not optimal but does the job. Thanks to Doug Stevenson for providing a link to helpful learning material. This similar post proved very helpful: Promise.all with Firebase DataSnapshot.forEach

...

var ref = admin.database().ref("modules/"+mod+"/Assignments");

return ref.once('value').then(function(snapshot) {
    var reads = [];

    snapshot.forEach(function(childSnapshot) {
        var id = childSnapshot.key;

        var ref = admin.database().ref("modules/"+mod+"/Assignments/"+id+"/"+uid);
        var promise = ref.once("value", function(mark) {
            // The Promise was fulfilled.
        }, function(error) {
            // The Promise was rejected.
            console.error(error);
        });
        reads.push(promise);
    });
    return Promise.all(reads);

}, function(error) {
    // The Promise was rejected.
    console.error(error);
}).then(function(values) { 
    total=0;
    count = values.length
    values.forEach(snap => {
      var data = parseInt(snap.node_.value_)
      total=total+data
    })
    var average = total/count;
    console.log(total)
    console.log(count)
    console.log(average)

    var reads = [];
    var p1 =admin.database().ref('/student/'+uid+"/modules/"+mod).set(average);
    var p2 =admin.database().ref('/student/'+uid+'/points/grades').transaction(function(prev){
      return parseInt(total,10)+score;
    });
    reads.push(p1);
    reads.push(p2);
    return Promise.all(reads);

});
Ryan
  • 1