在firebase中有一种方法可以快速连续地阻止写入吗?

时间:2016-05-12 13:20:53

标签: javascript jquery firebase

我写了一个非常简单的轮询脚本,可以将投票保存到Firebase数据库。为了防止同一个用户多次投票,我将电子邮件保存到一个单独的对象,然后在可以放置新条目之前检查它(这是我自己的信息,不需要高安全性)。

到目前为止它似乎确实阻止了基本的犯规,但是我得到了很多快速连续多次投票的实例(可能比浏览器重新加载的速度快)。在最糟糕的情况下,有16票相差毫秒。

有没有办法阻止这些快速连续写入Firebase或JavaScript端?

Firebase数据:

{
  "votes" : {
    " obj1 " : {
      "-KHXPWtcxzXhs2ULBE1Q" : {
        "name" : " name1 ",
        "email" : "email1",
        "timestamp" : 1463013744297
      },
      "-KHXPWuyhTg6S3Qcw4e9" : {
        "name" : " name1 ",
        "email" : "email1",
        "timestamp" : 1463013744382
      }
    },
    "obj2" : {
      "-KHZ20CRiT5fs6H4Nhel" : {
        "name" : "name2",
        "email" : "email2",
        "timestamp" : 1463041135613
      }
    },
  },
  "email" : {
    "-KHXPWtHSNYWBmvXsmNx" : {
      "email" : "email1",
      "timestamp" : 1463013744292
    },
    "-KHXPWus4hSwi1t00Gq_" : {
      "email" : "email1",
      "timestamp" : 1463013744377
    },
    "-KHZ20CdfcsoGjvn98Q" : {
      "email" : "email2",
      "timestamp" : 1463041135606
    },
  }
}

jQuery:

        var validateEmail = /^[A-Z0-9._%+-]+@([A-Z0-9-]+\.)+[A-Z]{2,4}$/i;

        function castVote() {

          var ref = new Firebase('firebaseurl');

          $( ".notification.exists" ).hide();
          $( ".notification.valid" ).hide();

          var obj = $('#obj').val().toLowerCase();
          var email = $('#email').val().toLowerCase();

          var emailref = ref.child("email");

          if (validateEmail.test(email)){
            emailref.once('value', function(snapshot) {
                var exists = false;
                snapshot.forEach(function(childSnapshot){
                    if(email === childSnapshot.val().email){
                        exists = true;     
                    }
                })

                if (exists){
                  $( ".notification.exists" ).show();
                }
                else{
                  write(obj,email,ref,emailref);
                }
            });
          }
          else{
            $( ".notification.valid" ).show();
          }
        }


        function write(obj,email,ref,emailref){

          var objref = ref.child("obj/" + obj);

          //save email
          emailref.push().set({
              email:email,
              "timestamp": Firebase.ServerValue.TIMESTAMP
            });

            //save vote
            objref.push().set({
              obj: obj,
              "email": email,
              "timestamp": Firebase.ServerValue.TIMESTAMP
            });

            //clear fields
            $('#obj').val('');
            $('#email').val('');
        }

      }

1 个答案:

答案 0 :(得分:5)

您应该使用安全规则在Firebase端阻止此操作。阻止用户重新投票的简单规则可以是 -

请注意,您需要将此代码段放在安全规则中的正确位置 -

"votes" : {
   // keep .read/.write as applicable
   "$obj" : {
        "$user" : {
            // keep .read/.write as applicable
            // Don't allow write if the parent obj already contains this user entry
            ".validate" : "!data.parent().hasChild($user)"
        }
   }
}

这样,一旦您为某个votes将用户的投票插入obj,另一次插入就会失败。