首页 > 解决方案 > 如何在 Firebase 中手动拍摄多个快照

问题描述

我正在使用 javascript 制作票证生成器。我正在使用 firebase 为用户提供已存储在数据库中的代码。我的数据库布局如下:

"qrcodes" : {
    "23KU8877" : {
          "email" : "person@email.com",
          "ticketgenerated" : "true"
    },
    "288RX9U5" : {
          "email" : "person2@email.com",
          "ticketgenerated" : "true"
    }
}

我的脚本允许我获取 qrcodes 列表中的第一个代码,然后将其移动到另一个数据库,由另一个网站处理它。但我想找到一种方法,让函数每次运行时都会拍摄一个新快照。

从 firebase 获取数据的函数在这里:

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

因此,如果上面的代码成功运行并获取 qrcode 列表的第一个子项(例如“23KU8877”),则无论函数循环多少次,它都将保持不变。

我不知道如何解决这个问题。任何帮助,将不胜感激。

谢谢,丹尼尔马丁内斯

标签: javascripthtmlfirebasefirebase-realtime-database

解决方案


您在一个紧密的循环中多次附加同一个侦听器。所有这些侦听器几乎在同一时间开始,因此都从数据库中看到相同的值。要获得下一个代码,您必须确保在删除前一个代码后才开始阅读下一个代码。一种常见的方法是使用递归函数:

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

因此,这段代码构建了一组 promise,每个异步发生的数据库操作都有一个。当所有这些操作完成后,它会用一个情人号码再次呼叫自己。

如果您createticket()还执行异步操作,您可能还希望将它包含在promises数组中,以便在下一次迭代开始之前完成它的工作。


推荐阅读