【问题标题】:Why is everything firing multiple times?为什么所有东西都会多次触发?
【发布时间】:2017-08-10 22:28:21
【问题描述】:

在我的 Ionic 应用中,当用户访问“位置”选项卡时,会对用户的帐户和相关业务进行一些操作。

现在,当一个键进入(基于 Geofire)时,一切都会被触发,但是它会触发多次,我不知道为什么!

例如,以毫秒为单位的时间将在推送时触发两次,并且推送的消息一次推送 8 或 9 次。

代码如下:

// Listen to every people in our query...
  geoQuery40.on("key_entered", function(key) {
    // ... and look them up by key ...
    restaurantsRef40.child(key).on("value", function(snapshot42) {
      var restaurant40 = snapshot42.val();
      var displayBusinessName = snapshot42.val().name;
      var displayBusinessDescription = snapshot42.val().description;
      var displayBusinessUid = snapshot42.val().uid;
      firebase.database().ref('accounts/' + userId + '/currentBusiness/').update({
        name: displayBusinessName,
        description: displayBusinessDescription,

        })
          //add the user in the Business' rotary

        var refRotary = firebase.database().ref('business/' + displayBusinessUid + '/rotary/' + userId);
        refRotary.once('value', function(snapshot78) {
          var displayVisit = snapshot78.val().lastVisit;
          var displayCurrentVisit = snapshot78.val().currentVisit;
          var displayWelcomeMessage = snapshot78.val().welcomeMessage;
          var displayBusinessPic = snapshot78.val().photoURL;
          $timeout(function() {
          $scope.displayVisit = displayVisit;
          $scope.displayCurrentVisit = displayCurrentVisit;
          $scope.displayWelcomeMessage = displayWelcomeMessage;
          $scope.displayBusinessPic = displayBusinessPic;

          if (displayCurrentVisit === undefined){
            firebase.database().ref('business/' + displayBusinessUid + '/rotary/' + userId).update({
              uid: userId,
              lastVisit: Date.now(),
              currentVisit: Date.now(),
            })
          } else {
        firebase.database().ref('business/' + displayBusinessUid + '/rotary/' + userId).update({
          uid: userId,
          lastVisit: displayCurrentVisit,
          currentVisit: Date.now(),
        })
}
          if (Date.now() - displayVisit > 3600000){
            firebase.database().ref('business/' + displayBusinessUid + '/rotary/' + userId + '/visits/').push({
              visit: Date.now(),
            })
          }

          var d = new Date();
          var g = new Date();
          d = d.toLocaleTimeString().replace(/:\d+ /, ' ');
          g = g.toLocaleTimeString().replace(/:\d+ /, ' ') + new Date();
          var refRotary2 = firebase.database().ref('business/' + displayBusinessUid);
          refRotary2.once('value', function(snapshot79) {
            var displayWelcomeMessage = snapshot79.val().welcomeMessage;
            var displayBusinessPic = snapshot79.val().photoURL;
            $timeout(function() {
              $scope.displayWelcomeMessage = displayWelcomeMessage;
            $scope.displayBusinessPic = displayBusinessPic;
          // envoie un message directement si c'est la premiere fois de la journee.
          var database = firebase.database();
          firebase.database().ref().child('/accounts/' + userId + '/discussions/' + userId + displayBusinessUid).set({
          blocked: 0,
          name: displayBusinessName,
          profilePic: displayBusinessPic,
          lastMessage: displayWelcomeMessage,
          time: d,
          discussionId: userId + displayBusinessUid,
          newMessages: 1,
          userId: displayBusinessUid,
          })
          firebase.database().ref().child('/messages/' + userId + displayBusinessUid).push({
          name: displayBusinessName,
          profilePic: displayBusinessPic,
          text: displayWelcomeMessage,
          time: d,
          userId: displayBusinessUid,
          })
          firebase.database().ref().child('/accounts/' + displayBusinessUid + '/discussions/' + userId + displayBusinessUid).set({
          name: displayBusinessName,
          profilePic: displayBusinessPic,
          lastMessage: displayWelcomeMessage,
          time: d,
          newMessages: 1,
          userId: displayBusinessUid,
          })
          // fin du message
        })
        })
        })

      })
        //end business rotary
    });
  });

【问题讨论】:

    标签: javascript angularjs firebase ionic-framework geofire


    【解决方案1】:

    我实际上在你的另一个问题中告诉过你这一点,但我猜你错过了。使用.on('value', [callback]) 时,您实际上是在为值更改事件注册一个侦听器,因此它会在每次值更改时触发,无论您的key_entered 是否被第二次触发。此值更改事件不仅会触发对您请求的对象的更改,还会触发对这些对象的任何子对象的任何更改。

    您应该使用 .once('value', [callback]) 代替您的 Firebase 请求(不是您的 key_entered-event,使用 .on(..) 是正确的)。

    示例

    这是您应该更改的代码部分:

    geoQuery40.on("key_entered", function(key) {
        //                          v-- Here's the change 
        restaurantsRef40.child(key).once("value", function(snapshot42) {
        ...
    

    【讨论】:

    • 您好,感谢您抽出宝贵时间回答,我对 Javascript 和 Firebase 比较陌生,所以我同时学习。对于 key_entered,我没有选择这是 Geofire 函数,我不能为此使用“Once”。您介意更正我的代码以便我可以尝试吗?我不确定是否正确理解。 (PS:对不起,由于某些原因我无法阅读其他讨论!)
    • 没问题。我实际上写道,使用带有 key_entered 事件的on 是正确的。但是下一行您将 on 与您的 Firebase 引用一起使用,这是注册侦听器的内容,而不仅仅是检索您的数据一次。有时,这就是你想要的,但在这种情况下,你会想要使用once(实际上你在代码中使用了once)。我会用更多代码更新我的答案。
    • 好吧,我会等你的代码,因为我在你所指的那一行使用了 ONCE,它的结果相同除以 2(推它 4 次而不是 8 !)也许我是别的失踪。谢谢你,我会等:)
    • 这是一个开始。 :-) 可能还有更多可以做的事情,但是你包含了很多代码,并且没有缩进使得它有点难以阅读。您应该尝试将代码分成更小的部分,例如在函数等中结合逻辑相似的代码,以提高可读性。未来你会因此爱上你。 ;-)
    • 谢谢 Nikolaj,我会将其标记为已解决,因为我几乎解决了这个问题,即使我确实仍有问题,确实可能是代码块使其难以执行!
    猜你喜欢
    • 2018-01-08
    • 1970-01-01
    • 2017-01-20
    • 2018-08-31
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    相关资源
    最近更新 更多