为什么所有东西都会多次发射?

Why is everything firing multiple times?

在我的 Ionic 应用程序中,当用户访问选项卡 "location" 时,会对用户帐户和相关业务进行一些操作。

现在,当输入一个键(基于 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
    });
  });

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

对于您的 Firebase 请求,您应该使用 .once('value', [callback])(不是您的 key_entered 事件,使用 .on(..) 是正确的)。

例子

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

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