Check out what’s new from Firebase at Google I/O 2022. Learn more

Pracuj z listami danych na Androidzie

Ten dokument opisuje pracę z listami danych w Firebase. Aby nauczyć się podstaw czytania i pisania danych Firebase zobaczyć odczytu i zapisu danych na Androidzie .

Otrzymuj DatabaseReference

Do odczytu i zapisu danych z bazy danych, trzeba instancję DatabaseReference :

Java

private DatabaseReference mDatabase;
// ...
mDatabase = FirebaseDatabase.getInstance().getReference();

Kotlin+KTX

private lateinit var database: DatabaseReference
// ...
database = Firebase.database.reference

Czytać i pisać listy

Dołącz do listy danych

Użyj push() metody, aby dołączyć dane do listy w aplikacji dla wielu użytkowników. push() metoda generuje unikalny klucz za każdym razem nowe dziecko jest dodawany do określonego odniesienia Firebase. Za pomocą tych klawiszy generowane automatycznie dla każdego nowego elementu na liście, kilka klienci mogą dodawać dzieci w tym samym miejscu w tym samym czasie, bez konfliktów zapisu. Unikatowy klucz generowany przez push() jest oparty na datownik, więc elementy listy są automatycznie uporządkowane chronologicznie.

Można użyć odniesienie do nowych danych zwracanych przez push() metoda, aby uzyskać wartość generowanych automatycznie kluczowych lub zestaw danych dziecka do dziecka. Wywołanie getKey() na push() odniesienie zwraca wartość klucza generowanego automatycznie.

Można użyć tych klawiszy generowane automatycznie, aby uprościć spłaszczenie struktury danych. Aby uzyskać więcej informacji, zobacz fan-out danych przykład .

Nasłuchiwania zdarzeń podrzędnych

Podczas pracy z listami, aplikacja powinna słuchać na imprezach dziecięcych zamiast wydarzeń wartości stosowanych dla pojedynczych obiektów.

Imprezy dla dzieci są wywoływane w odpowiedzi na konkretne działania, które zdarzają się dzieciom węzła z operacji, takich jak nowe dziecko dodanego przez push() metody lub dziecka aktualizowany przez updateChildren() metody. Każdy z nich razem mogą być przydatne do słuchania zmian do węzła określonego w bazie danych.

Aby słuchać na imprezach Dziecko na DatabaseReference , załączyć ChildEventListener :

Słuchacz zwrotna wydarzenie typowe zastosowanie
ChildEventListener onChildAdded() Pobrać listy przedmiotów lub słuchać uzupełnień do listy przedmiotów. Ta funkcja zwrotna jest wyzwalany raz dla każdego istniejącego dziecka, a następnie ponownie za każdym razem nowe dziecko jest dodawany do określonej ścieżce. DataSnapshot przeszedł do słuchacza zawiera dane nowego dziecka.
onChildChanged() Nasłuchiwać zmian pozycji na liście. To wydarzenie zwolniony każdej chwili węzeł dziecko jest modyfikowany, w tym wszelkie modyfikacje potomków węzła potomnego. DataSnapshot przekazywane do detektora zdarzeń zawiera zaktualizowane dane dla dziecka.
onChildRemoved() Nasłuchiwać przedmioty są usuwane z listy. DataSnapshot przekazany do wywołania zwrotnego zdarzenia zawiera dane dla usuniętego dziecka.
onChildMoved() Słuchaj na zmiany kolejności elementów w uporządkowanej listy. To zdarzenie jest wywoływane, gdy onChildChanged() callback jest wyzwalany przez aktualizacji, która powoduje zmianę kolejności od dziecka. Jest on używany z danych, które są zamawiane z orderByChild lub orderByValue .

Na przykład, aplikacja do blogowania społecznej może korzystać z tych metod razem, aby monitorować aktywność w komentarzach do postu, jak pokazano poniżej:

Java

ChildEventListener childEventListener = new ChildEventListener() {
    @Override
    public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
        Log.d(TAG, "onChildAdded:" + dataSnapshot.getKey());

        // A new comment has been added, add it to the displayed list
        Comment comment = dataSnapshot.getValue(Comment.class);

        // ...
    }

    @Override
    public void onChildChanged(DataSnapshot dataSnapshot, String previousChildName) {
        Log.d(TAG, "onChildChanged:" + dataSnapshot.getKey());

        // A comment has changed, use the key to determine if we are displaying this
        // comment and if so displayed the changed comment.
        Comment newComment = dataSnapshot.getValue(Comment.class);
        String commentKey = dataSnapshot.getKey();

        // ...
    }

    @Override
    public void onChildRemoved(DataSnapshot dataSnapshot) {
        Log.d(TAG, "onChildRemoved:" + dataSnapshot.getKey());

        // A comment has changed, use the key to determine if we are displaying this
        // comment and if so remove it.
        String commentKey = dataSnapshot.getKey();

        // ...
    }

    @Override
    public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) {
        Log.d(TAG, "onChildMoved:" + dataSnapshot.getKey());

        // A comment has changed position, use the key to determine if we are
        // displaying this comment and if so move it.
        Comment movedComment = dataSnapshot.getValue(Comment.class);
        String commentKey = dataSnapshot.getKey();

        // ...
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
        Log.w(TAG, "postComments:onCancelled", databaseError.toException());
        Toast.makeText(mContext, "Failed to load comments.",
                Toast.LENGTH_SHORT).show();
    }
};
databaseReference.addChildEventListener(childEventListener);

Kotlin+KTX

val childEventListener = object : ChildEventListener {
    override fun onChildAdded(dataSnapshot: DataSnapshot, previousChildName: String?) {
        Log.d(TAG, "onChildAdded:" + dataSnapshot.key!!)

        // A new comment has been added, add it to the displayed list
        val comment = dataSnapshot.getValue<Comment>()

        // ...
    }

    override fun onChildChanged(dataSnapshot: DataSnapshot, previousChildName: String?) {
        Log.d(TAG, "onChildChanged: ${dataSnapshot.key}")

        // A comment has changed, use the key to determine if we are displaying this
        // comment and if so displayed the changed comment.
        val newComment = dataSnapshot.getValue<Comment>()
        val commentKey = dataSnapshot.key

        // ...
    }

    override fun onChildRemoved(dataSnapshot: DataSnapshot) {
        Log.d(TAG, "onChildRemoved:" + dataSnapshot.key!!)

        // A comment has changed, use the key to determine if we are displaying this
        // comment and if so remove it.
        val commentKey = dataSnapshot.key

        // ...
    }

    override fun onChildMoved(dataSnapshot: DataSnapshot, previousChildName: String?) {
        Log.d(TAG, "onChildMoved:" + dataSnapshot.key!!)

        // A comment has changed position, use the key to determine if we are
        // displaying this comment and if so move it.
        val movedComment = dataSnapshot.getValue<Comment>()
        val commentKey = dataSnapshot.key

        // ...
    }

    override fun onCancelled(databaseError: DatabaseError) {
        Log.w(TAG, "postComments:onCancelled", databaseError.toException())
        Toast.makeText(context, "Failed to load comments.",
                Toast.LENGTH_SHORT).show()
    }
}
databaseReference.addChildEventListener(childEventListener)

Nasłuchiwania zdarzeń wartości

Podczas korzystania z ChildEventListener jest zalecanym sposobem, aby przeczytać list danych, istnieją sytuacje, w których dołączenie ValueEventListener do odniesienia lista jest użyteczna.

Dołączanie ValueEventListener do listy danych zwróci całą listę danych jako pojedynczy DataSnapshot , które można następnie pętli nad dostępu do poszczególnych dzieci.

Nawet wtedy, gdy istnieje tylko jeden mecz dla zapytania, migawka nadal jest lista; to po prostu zawiera pojedynczy element. Aby uzyskać dostęp do elementu, trzeba pętli nad wynikiem:

Java

// My top posts by number of stars
myTopPostsQuery.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) {
            // TODO: handle the post
        }
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
        // Getting Post failed, log a message
        Log.w(TAG, "loadPost:onCancelled", databaseError.toException());
        // ...
    }
});

Kotlin+KTX

// My top posts by number of stars
myTopPostsQuery.addValueEventListener(object : ValueEventListener {
    override fun onDataChange(dataSnapshot: DataSnapshot) {
        for (postSnapshot in dataSnapshot.children) {
            // TODO: handle the post
        }
    }

    override fun onCancelled(databaseError: DatabaseError) {
        // Getting Post failed, log a message
        Log.w(TAG, "loadPost:onCancelled", databaseError.toException())
        // ...
    }
})

Wzór ten może być przydatny, gdy chcemy pobrać wszystkie dzieci z listy w jednej operacji, zamiast słuchać dodatkowych onChildAdded wydarzeń.

Odłącz słuchaczy

Oddzwaniania są usuwane poprzez wywołanie removeEventListener() metody na swojej Firebase odniesienia bazy danych.

Jeżeli słuchacz został dodany wielokrotnie do lokalizacji danych, nazywa się to wiele razy dla każdego zdarzenia i należy je odłączyć taką samą liczbę razy, aby usunąć go całkowicie.

Wywołanie removeEventListener() na słuchacza dominującej nie powoduje automatycznego usunięcia detektory zarejestrowane na jego węzłów potomnych; removeEventListener() musi być również nazywane na wszelkich detektorów podrzędnych do usunięcia zwrotnego.

Sortowanie i filtrowanie danych

Można użyć Realtime Database Query klasy odzyskać dane posortowane według klucza, według wartości, lub według wartości dziecka. Można także filtrować posortowaną wynik określonej liczby wyników lub wielu klawiszy lub wartości.

Sortowanie danych

Aby pobrać dane sortowane, zacząć od określenia jednego z rzędu-metodami określenia jak wyniki są sortowane:

metoda Stosowanie
orderByChild() Wyniki Sortuj według wartości określonego klucza dzieci lub zagnieżdżonego ścieżce dziecięcej.
orderByKey() Wyniki Zamówienie przez klawisze dziecko.
orderByValue() Wyniki Sortuj według wartości dziecka.

Można użyć tylko jednego zleceniami metodą naraz. Wywołanie zleceniami od czasów metoda wielu w tej samej kwerendy generuje błąd.

Poniższy przykład pokazuje, jak można pobrać listę najlepszych posty użytkownika, posortowane według ich liczby gwiazdy:

Java

// My top posts by number of stars
String myUserId = getUid();
Query myTopPostsQuery = databaseReference.child("user-posts").child(myUserId)
        .orderByChild("starCount");
myTopPostsQuery.addChildEventListener(new ChildEventListener() {
    // TODO: implement the ChildEventListener methods as documented above
    // ...
});

Kotlin+KTX

// My top posts by number of stars
val myUserId = uid
val myTopPostsQuery = databaseReference.child("user-posts").child(myUserId)
    .orderByChild("starCount")

myTopPostsQuery.addChildEventListener(object : ChildEventListener {
    // TODO: implement the ChildEventListener methods as documented above
    // ...
})

To określa zapytanie, które w połączeniu ze słuchaczem dziecka synchronizuje klientowi postów użytkownika ze ścieżki w bazie danych na podstawie ich identyfikatora użytkownika, uporządkowane według liczby gwiazd każdy post odebranych. Ta technika z użyciem identyfikatorów kluczy indeksowych jak nazywa wentylatora danych out, można przeczytać więcej na ten temat w strukturze bazy danych .

Wezwanie do orderByChild() metody określa klucz dziecko na zamówienie wyników przez. W tym przypadku, słupki są klasyfikowane według wartości ich odpowiednich "starCount" dziecka. Zapytania można również zamówić przez zagnieżdżone dzieci, w przypadku gdy masz dane, które wygląda następująco:

"posts": {
  "ts-functions": {
    "metrics": {
      "views" : 1200000,
      "likes" : 251000,
      "shares": 1200,
    },
    "title" : "Why you should use TypeScript for writing Cloud Functions",
    "author": "Doug",
  },
  "android-arch-3": {
    "metrics": {
      "views" : 900000,
      "likes" : 117000,
      "shares": 144,
    },
    "title" : "Using Android Architecture Components with Firebase Realtime Database (Part 3)",
    "author": "Doug",
  }
},

W tym przykładzie, możemy zamówić naszą listę elementów wartościami zagnieżdżone pod metrics klucza określając ścieżkę względną do zagnieżdżonego dziecka w naszym orderByChild() rozmowy.

Java

// Most viewed posts
Query myMostViewedPostsQuery = databaseReference.child("posts")
        .orderByChild("metrics/views");
myMostViewedPostsQuery.addChildEventListener(new ChildEventListener() {
    // TODO: implement the ChildEventListener methods as documented above
    // ...
});

Kotlin+KTX

// Most viewed posts
val myMostViewedPostsQuery = databaseReference.child("posts")
        .orderByChild("metrics/views")
myMostViewedPostsQuery.addChildEventListener(object : ChildEventListener {
    // TODO: implement the ChildEventListener methods as documented above
    // ...
})

Aby uzyskać więcej informacji o tym, jak inne typy danych są sortowane, zobacz Jak kwerendy danych jest uporządkowane .

filtrowanie danych

Do filtrowania danych, można połączyć dowolną z metod dopuszczalnych lub zakresu zamówienia, z metodą przy konstruowaniu kwerendy.

metoda Stosowanie
limitToFirst() Ustawia maksymalną liczbę elementów, aby powrócić od początku uporządkowanej listy wyników.
limitToLast() Ustawia maksymalną liczbę elementów, aby powrócić z końca uporządkowanej listy wyników.
startAt() Zwraca elementy większa lub równa do określonego klucza lub wartości w zależności od celu-by wybranej metody.
startAfter() Zwraca elementy większe niż określonego klucza lub wartości w zależności od kolejności, metodą wybrany.
endAt() powrotne rzeczy mniejsza lub równa podanej klucza lub wartości w zależności od celu-by wybranej metody.
endBefore() Zwraca elementy mniej niż określonego klucza lub wartości w zależności od kolejności, metodą wybrany.
equalTo() powrotne rzeczy równa określonego klucza lub wartości w zależności od celu-by wybranej metody.

W przeciwieństwie do celu, za pomocą metod, można połączyć kilka funkcji granicznych lub zakres. Na przykład, można połączyć startAt() i endAt() metod, aby ograniczyć wyniki do określonego zakresu wartości.

Nawet wtedy, gdy istnieje tylko jeden mecz dla zapytania, migawka nadal jest lista; to po prostu zawiera pojedynczy element. Aby uzyskać dostęp do elementu, trzeba pętli nad wynikiem:

Java

// My top posts by number of stars
myTopPostsQuery.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) {
            // TODO: handle the post
        }
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
        // Getting Post failed, log a message
        Log.w(TAG, "loadPost:onCancelled", databaseError.toException());
        // ...
    }
});

Kotlin+KTX

// My top posts by number of stars
myTopPostsQuery.addValueEventListener(object : ValueEventListener {
    override fun onDataChange(dataSnapshot: DataSnapshot) {
        for (postSnapshot in dataSnapshot.children) {
            // TODO: handle the post
        }
    }

    override fun onCancelled(databaseError: DatabaseError) {
        // Getting Post failed, log a message
        Log.w(TAG, "loadPost:onCancelled", databaseError.toException())
        // ...
    }
})

Ograniczyć liczbę wyników

Można użyć limitToFirst() i limitToLast() metody, aby ustawić maksymalną liczbę dzieci, które mają być synchronizowane za dany zwrotnego. Na przykład, jeśli używasz limitToFirst() , aby ustawić limit 100, początkowo tylko otrzymać do 100 onChildAdded() wywołania zwrotne. Jeśli masz mniej niż 100 przedmiotów przechowywanych w bazie danych onChildAdded() pożary wywołania zwrotnego dla każdej pozycji.

Jak zmienić pozycji, onChildAdded() wywołania zwrotne dla elementów, które wchodzą zapytanie i onChildRemoved() wywołania zwrotne dla elementów, które wypadają z niego tak, że całkowita liczba pobytów na 100.

Poniższy przykład pokazuje, jak przykład blogów aplikacja definiuje kwerendę, aby pobrać listę 100 ostatnio wysłane przez wszystkich użytkowników:

Java

// Last 100 posts, these are automatically the 100 most recent
// due to sorting by push() keys
Query recentPostsQuery = databaseReference.child("posts")
        .limitToFirst(100);

Kotlin+KTX

// Last 100 posts, these are automatically the 100 most recent
// due to sorting by push() keys.
databaseReference.child("posts").limitToFirst(100)

Przykład ten określa jedynie zapytanie, aby zsynchronizować dane rzeczywiście musi mieć dołączony słuchacza .

Filtrowanie według klucza lub wartości

Można użyć startAt() , startAfter() , endAt() , endBefore() , a equalTo() , aby wybrać dowolnego wyjścia, kończy, a punkty równorzędności zapytaniami. Może to być użyteczne dla Stronicowanie danych lub znajdowaniu przedmiotów z dziećmi, które mają wartość konkretnego.

Jak dane zapytanie jest uporządkowane

Ta sekcja wyjaśnia, w jaki sposób dane są klasyfikowane według każdego z metodami zleceniami w Query klasy.

orderByChild

Podczas korzystania orderByChild() , dane, które zawiera określony klucz dziecko zarządza się, co następuje:

  1. Dzieci z null wartością dla określonego klucza dziecka na pierwszym miejscu.
  2. Dzieci z wartością false dla określonego klucza dziecko przyjdzie następny. Jeśli wiele dzieci ma wartość false , są one klasyfikowane leksykograficznie przez klucz.
  3. Dzieci o wartości true dla określonego klucza dziecko przyjdzie następny. Jeśli wiele dzieci ma wartość true , są one klasyfikowane leksykograficznie przez klucz.
  4. Dzieci z wartością liczbową przyszłym, sortowane w porządku rosnącym. Jeśli wiele dzieci mają taką samą wartość liczbową dla określonego węzła potomnego, są klasyfikowane według klucza.
  5. Struny przyjść po liczbie i są klasyfikowane leksykograficznie w porządku rosnącym. Jeśli wiele dzieci mają taką samą wartość dla określonego węzła potomnego, są one zamawiane leksykograficznie przez klucz.
  6. Przedmioty pochodzą ostatni i są klasyfikowane leksykograficznie przez klucz w porządku rosnącym.

orderByKey

Podczas korzystania orderByKey() do sortowania danych, dane są zwracane w kolejności rosnącej według klucza.

  1. Dzieci z kluczem, który może być analizowany jako 32-bitowa liczba całkowita kto pierwszy, sortowane w porządku rosnącym.
  2. Dzieci o wartości ciąg jako klucz ich przyszłym, sortowane leksykograficznie w porządku rosnącym.

orderByValue

Podczas korzystania orderByValue() , dzieci są sortowane według ich wartości. Kryteria porządkowania są takie same jak w orderByChild() , z wyjątkiem wartość węzła jest używana zamiast wartości określonego klucza podrzędnego.

Następne kroki