Daniel Martinez
Daniel Martinez

Reputation: 53

How can I manually take multiple snapshots in firebase

I am making a ticket generator using javascript. I am using firebase to give the users a code that has already been stored on the database. my database is layed out like this:

"qrcodes" : {
    "23KU8877" : {
          "email" : "[email protected]",
          "ticketgenerated" : "true"
    },
    "288RX9U5" : {
          "email" : "[email protected]",
          "ticketgenerated" : "true"
    }
}

my script allows me to get the first code in the qrcodes list and then move it to another database where another website processes it. But I was wanting to find a way that will make a function take a new snapshot everytime it is run.

The functions that grab the data from firebase are here:

function generatehtml(){
    ticketname = document.getElementById('name').value;
    ticketemail = document.getElementById('email').value;
    adultnumber = document.getElementById('adults').value;
    childnumber = document.getElementById('child').value;

    while (functionruncount < inputnumber){
        grabfirebasecode();
    }    
}

function grabfirebasecode(){
    ref.limitToFirst(1).once('value', function(snapshot) {
            for(key in snapshot.val()){
                genvar = snapshot.child(key + "/ticketgenerated" ).val();
                var genvarpath = "test/" + key + "/ticketgenerated";
                if (genvar === "false"){
                    snapshot.forEach(function(childSnapshot) {
                        ref.child(childSnapshot.key).remove();
                    });
                    ref2.child(key).set({
                        email: ticketemail,
                        ticketgenerated: "true",
                    });
                    createticket();
                } 
            }

        });
    functionruncount ++;
}

so if the code above runs succesully and grabs the first child of the qrcode list (e.g "23KU8877"), it will stay the same no matter how many times the function loops.

I am not sure how to fix this. Any help would be appreciated.

Thanks, Daniel Martinez

Upvotes: 0

Views: 295

Answers (1)

Frank van Puffelen
Frank van Puffelen

Reputation: 598740

You're attaching a same listener multiple times in a tight loop. All those listeners start at pretty much the same time, and thus all see the same value from the database. To get a next code, you must be sure to only start reading the next code after you've deleted the previous one. A common way to do this is with a recursive function:

function generatehtml(){
    ticketname = document.getElementById('name').value;
    ticketemail = document.getElementById('email').value;
    adultnumber = document.getElementById('adults').value;
    childnumber = document.getElementById('child').value;

    grabfirebasecode(inputnumber);
}

function grabfirebasecode(inputnumber){
  if (inputnumber > 0) {
    ref.limitToFirst(1).once('value', function(snapshot) {
        for(key in snapshot.val()){
            genvar = snapshot.child(key + "/ticketgenerated" ).val();
            var genvarpath = "test/" + key + "/ticketgenerated";
            if (genvar === "false"){
                var promises = [];
                snapshot.forEach(function(childSnapshot) {
                    promises.push(ref.child(childSnapshot.key).remove());
                });
                promises.push(
                  ref2.child(key).set({
                    email: ticketemail,
                    ticketgenerated: "true",
                  })
                );
                Promise.all(promises).then(function() {
                  grabfirebasecode(inputnumber-1);
                });
                createticket();
            } 
        }
    });
  }
}

So this code builds an array of promises, one for each database operation that happen asynchronously. When all those operations completes, it calls itself again with one lover number.

If your createticket() also performs asynchronous operations, you might want to also include it in the promises array so that its work is completed before the next iteration starts.

Upvotes: 1

Related Questions