2012-08-03 15 views
39

Z Firebase API:Firebase child_added tylko dostać dziecko dodał

Child Dodano: To zdarzenie zostanie wyzwolony raz dla każdego początkowego dziecka w tym miejscu, i będzie uruchamiany ponownie za każdym razem nową dziecko jest dodany.

Niektóre kodu:

listRef.on('child_added', function(childSnapshot, prevChildName) { 
    // do something with the child 
}); 

Ale ponieważ funkcja jest wywoływana raz na każde dziecko w tym miejscu, czy jest jakiś sposób, aby tylko dziecko, które zostało faktycznie dodanej?

+10

Dlaczego ta metoda nie działa tak, jak powinna? Powinno to zrobić tylko jedną rzecz - wywołać w dowolnym momencie, gdy dziecko zostanie dodane - nic więcej. –

+2

Tak, zgadzam się, że Browne .męczy się ... –

Odpowiedz

29

Aby śledzić rzeczy dodanych od jakiegoś punktu kontrolnego bez pobierania poprzednie rekordy, można użyć endAt() i limit() złapać ostatni rekord:

// retrieve the last record from `ref` 
ref.endAt().limit(1).on('child_added', function(snapshot) { 

    // all records after the last continue to invoke this function 
    console.log(snapshot.name(), snapshot.val()); 

}); 
+0

W zasadzie odkryłem prostsze podejście, ponieważ nadal powiadamia o dodanych zdarzeniach, nawet po osiągnięciu limitu(). Odpowiednio zaktualizowałem swoją odpowiedź. – Kato

+1

Nie jest jasne, co masz na myśli. Działa to tylko na zamówionych zestawach, ale jeśli potrzebujesz zamówić coś innego (poza zamówionym zestawem?) ... Twój komentarz nie pomoże też nikomu zrozumieć, jak uzyskać dodane przez dziecko zdarzenia w Firebase. – Kato

+1

Funkcja wywołania zwrotnego uruchamia się tylko raz dla rekordu zwróconego przez 'ref.endAt(). Limit (1)'. Nie uruchamia innych nowych rekordów dodanych po tym rekordzie. Testuję to z Angularfire 0.8.0 – Waseem

28

limit() metoda jest przestarzała. limitToLast() i limitToFirst() metody go zastąpią.

// retrieve the last record from `ref` 
ref.limitToLast(1).on('child_added', function(snapshot) { 

    // all records after the last continue to invoke this function 
    console.log(snapshot.name(), snapshot.val()); 
    // get the last inserted key 
    console.log(snapshot.key()); 

}); 
+3

Próbowałem tego podejścia, ale należy zwrócić uwagę na jedno: jeśli ostatni rekord zostanie usunięty, na przykład użytkownik opublikuje komentarz i usunie go poprawnie od (na przykład błąd) powyższa funkcja .on() zostanie wywołana ponownie. Rozwiązałem dodawanie znacznika czasu i sprawdzanie, czy dodane dziecko ma mniej niż 1 sekundę, jeśli jest starsze, jest to stara płyta i nie zostało dodane. W tym celu zajrzyj do ref.child ('. Info') – DivZero

+2

Nie rozumiem - czy to nie jest ostatni przedmiot? Co powiesz na "tylko elementy dodane po powiązaniu z tym wydarzeniem"? –

+0

Tak, zastanawiasz się tak samo. Otrzymuje on tylko ostatni element, a następnie nie uruchamia innych dodanych zdarzeń. – Orlando

0

Dla mnie logika ma mieć wartość - „status” na przykład-, który musi zostać zatwierdzony przed podjęciem decyzji, czy to naprawdę był nowy lub stary rekord następnie ustawić „status” na inny wartość, więc nie dostać go następnym razem:

@Override 
     public void onChildAdded(DataSnapshot dataSnapshot, String previousChildKey) { 

       if(dataSnapshot.hasChildren()) { 

        String Id = (String) dataSnapshot.child("user_id").getValue(); 
        String status = (String) dataSnapshot.child("status").getValue(); 

        if (Id != null && Id.equals(storedId) && status != null && status.equals("created")) { 
         Log.d("INCOMING_REQUEST", "This is for you!"); 
         sessionsRef.child(dataSnapshot.getKey()).child("status").setValue("received"); 
        } 

       } 


     } 
0

Swift3 Rozwiązanie:

Możesz odzyskać swoje poprzednie dane za pomocą następującego kodu:

queryRef?.observeSingleEvent(of: .value, with: { (snapshot) in 
     //Your code 

    }) 

, a następnie obserwuj nowe dane za pomocą następującego kodu.

queryRef?.queryLimited(toLast: 1).observe(.childAdded, with: { (snapshot) in 

//Your Code 

     }) 
1

Próbowałem innych sposobów odpowiedzi, ale wywołałem przynajmniej raz dla ostatniego dziecka. Jeśli masz klucz czasu w swoich danych, możesz to zrobić.

ref.orderByChild('createdAt').startAt(Date.now()).on('child_added', ... 
1

Ponieważ wywołanie metody ref.push() bez danych generuje klucze ścieżki w oparciu o czas, to co zrobiłem:

// Get your base reference 
const messagesRef = firebase.database().ref().child("messages"); 

// Get a firebase generated key, based on current time 
const startKey = messagesRef.push().key; 

// 'startAt' this key, equivalent to 'start from the present second' 
messagesRef.orderByKey().startAt(startKey) 
.on("child_added", 
    (snapshot)=>{ /*Do something with future children*/} 
); 

Zauważ, że nic nie jest faktycznie napisane do odniesienia (lub „klucz”), które Zwrócono kod ref.push(), więc nie trzeba przechwytywać pustych danych.

Powiązane problemy