5

Myślę, że aktualizacja firebase function listy, którą mam w firebase database jest przechwytywana przez subscription, która jest subskrybowana do tej listy. Z tego, co wygląda na wyjściu listy na moim telefonie (w aplikacji) ... i z tego, jak wygląda moje wyjście konsoli (sposób, w jaki się powtarza), wygląda na to, że przechwytuje całą listę i wyświetla ją za każdym razem, gdy jest dodawany. Tak (I wyglądało to w górę) ... Wierzę, że to równanie reprezentuje to, co się dzieje:Wykonanie funkcji Firebase i subskrypcji do listy, która jest aktualizowana przez funkcję firebase

(N(N + 1))/2

To jak dostać sumę wszystkich liczb od 1 do N. Doing matematyki w moim Przypadek (N = 30 lub mniej), dostaję około 465 wpisów ... więc widzisz, że ładuje tonę, kiedy chcę tylko załadować pierwszą 10.

Aby pokazać, co dzieje się z wyjściem tutaj jest pastebin https://pastebin.com/B7yitqvD.

Na wyjściu należy zwrócić uwagę na tablicę znajdującą się powyżej/przed numerem length - 1 load. Widać, że szybko zwraca tablicę z jeszcze jednym wpisem za każdym razem i dodaje go do listy. Zrobiłem bardzo nieokreśloną liczbę elementów na mojej liście, a dostałem 440 ... tak, że z grubsza pasuje do numeru 465.

Łańcuch zdarzeń rozpoczyna się w stronę, która nie jest strona z listą z tej funkcji - który inicjuje sortowania po stronie firebase functions:

let a = this.http.get('https://us-central1-mane-4152c.cloudfunctions.net/sortDistance?text='+resp.coords.latitude+':'+resp.coords.longitude+':'+this.username); 
this.subscription6 = a.subscribe(res => { 
console.log(res + "response from firesbase functions"); 
    loading.dismiss(); 
}, err => { 
    console.log(JSON.stringify(err)) 
    loading.dismiss(); 
}) 

Oto funkcja na stronie z list Myślę, że z jakiegoś powodu przechwytuje cały rodzaj. Subskrypcja jest powtarzana, jak sądzę, w rodzajach firebase function.

loadDistances() { 
    //return new Promise((resolve, reject) => { 
     let cacheKey = "distances" 
     let arr = []; 
     let mapped; 
     console.log("IN LOADDISTANCES #$$$$$$$$$$$$$$$$$$$$$"); 


     console.log("IN geo get position #$$$$$$$5354554354$$$$$$$"); 

     this.distancelist = this.af.list('distances/' + this.username, { query: { 
      orderByChild: 'distance', 
      limitToFirst: 10 
     }}); 


     this.subscription6 = this.distancelist.subscribe(items => { 
      let x = 0; 

      console.log(JSON.stringify(items) + "  length - 1 load"); 



      items.forEach(item => { 
      let storageRef = firebase.storage().ref().child('/settings/' + item.username + '/profilepicture.png'); 

       storageRef.getDownloadURL().then(url => { 
       console.log(url + "in download url !!!!!!!!!!!!!!!!!!!!!!!!"); 
       item.picURL = url; 
       }).catch((e) => { 
       console.log("in caught url !!!!!!!$$$$$$$!!"); 
       item.picURL = 'assets/blankprof.png'; 
       }); 

      this.distances.push(item); 

      if(x == items.length - 1) { 
       this.startAtKey4 = items[x].distance; 
      } 

      x++; 
      }) 

      //this.subscription6.unsubscribe(); 
     }) 

    } 

subscription w loadDistances funkcja działa w porządku tak długo, jak nie aktualizuje listę z drugiej strony - kolejny wskaźnik, który może być przechwytywanie całego rodzaju wystawianie go wielokrotnie, gdyż sortuje.

Próbowałem jak mogłem wymyślić unsubscribe z listy po aktualizacji ... więc mógłbym załadować listę 10 następnym razem, gdy strona z listą wchodzi, zamiast zaraz po aktualizacji (w kółko). Wiem, że firebase functions jest w beta. Czy to może być błąd po ich stronie? Oto mój kod firebase functions:

exports.sortDistance = functions.https.onRequest((req, res) => { 
    // Grab the text parameter. 
    var array = req.query.text.split(':'); 
    // Push the new message into the Realtime Database using the Firebase Admin SDK. 
    // Get a database reference to our posts 
    var db = admin.database(); 
    var ref = db.ref("profiles/stylists"); 
    var promises = []; 
    // Attach an asynchronous callback to read the data at our posts reference 
    ref.on("value", function(snapshot) { 
     //console.log(snapshot.val()); 
     var snap = snapshot.val(); 
     for(const user in snap) { 
     promises.push(new Promise(function(resolve, reject) { 
      var snapadd = snap[user].address; 
      console.log(snapadd + " snap user address (((((((())))))))"); 
      if(snapadd != null || typeof snapadd != undefined) { 
        googleMapsClient.geocode({ 
         address: snapadd 
        }).asPromise() 
         .then(response => { 
          console.log(response.json.results[0].geometry.location.lat); 


          console.log(" +++ " + response.json.results[0].geometry.location.lat + ' ' + response.json.results[0].geometry.location.lng + ' ' + array[0] + ' ' + array[1]); 


          var distanceBetween = distance(response.json.results[0].geometry.location.lat, response.json.results[0].geometry.location.lng, array[0], array[1]); 
          console.log(distanceBetween + "  distance between spots"); 
          var refList = db.ref("distances/"+array[2]); 
          console.log(snap[user].username + " snap username"); 
          refList.push({ 
          username: snap[user].username, 
          distance: Math.round(distanceBetween * 100)/100 
          }) 

          resolve(); 
         }) 
         .catch(err => { console.log(err); resolve();}) 
      } 
      else { 
       resolve(); 
      } 
     }).catch(err => console.log('error from catch ' + err))); 
     //console.log(typeof user + 'type of'); 

     } 

     var p = Promise.all(promises); 
     console.log(JSON.stringify(p) +  "  promises logged"); 

     res.status(200).end(); 

    }, function (errorObject) { 
     console.log("The read failed: " + errorObject.code); 
    }); 
}); 

Co jest dziwne jest, kiedy sprawdzić firebase functions dzienniki, wszystko to wydaje się uruchomić tylko raz ... ale ja nadal uważam, że subskrypcja może być przechwytywanie cały proces sortowania jakiś dziwny sposób, a jednocześnie szybko go zwróci. Aby być jak najbardziej zrozumiałym w tym, co myślę dzieje - myślę, że każdy etap tego rodzaju jest przechwytywany w (N(N + 1))/2 ... zaczynając od 1 i przechodząc do około 30 ... a suma sortowania kończy się długość mojej listy (z powtarzaniem w kółko od 1 do 10 pozycji).

+0

Chociaż wskazane na [poprzedniej instancji to pytanie] (https://stackoverflow.com/q/47561946/4815718), że to nie rozwiąże problemu, nadal powinieneś używać 'once()' zamiast 'on()' here: 'ref.on ("value", function (snapshot) '. –

+0

Próbowałem, że ... i wydawało się, że nic nie działa ... źle, spróbuj ponownie ... i ponownie sprawdź logi funkcji firebase, aby zobaczyć, czy coś zostanie wykonane i ts nie tylko pojawia się w mojej aplikacji – ewizard

+0

Gdy liczba operacji asynchronicznych staje się duża, jak to jest w Cloud 'sortDistance', trudno jest poprawnie połączyć wszystkie obietnice. Wygląda na to, że próbowałeś, ale niektóre zostały pominięte, na przykład tutaj: 'refList.push (...)'. –

Odpowiedz

0

Zaktualizowałem do angularfire2 5.0 i angular 5.0 ...która miała trochę czasu, ale skończyło się na rozwiązywaniu problemu:

this.distanceList = this.af.list('/distances/' + this.username, 
    ref => ref.orderByChild("distance").limitToFirst(50)).valueChanges(); 

w moim HTML użyłem async rury, który rozwiązał sortowania problem:

... 

<ion-item *ngFor="let z of (distanceList|async)" no-padding> 

...