Bu doküman, Firebase'deki veri listeleriyle çalışmayı kapsar. Firebase verilerini okuma ve yazmayla ilgili temel bilgileri öğrenmek için Android'de Veri Okuma ve Yazma başlıklı makaleyi inceleyin.
DatabaseReference alma
Veritabanında veri okumak ve yazmak için DatabaseReference
örneğine ihtiyacınız vardır:
Kotlin+KTX
private lateinit var database: DatabaseReference // ... database = Firebase.database.reference
Java
private DatabaseReference mDatabase; // ... mDatabase = FirebaseDatabase.getInstance().getReference();
Listeleri okuma ve yazma
Veri listesine ekleme
Çok kullanıcılı uygulamalarda bir listeye veri eklemek için push()
yöntemini kullanın.
push()
yöntemi, belirtilen Firebase referansına her yeni çocuk eklendiğinde benzersiz bir anahtar oluşturur. Listedeki her yeni öğe için bu otomatik olarak oluşturulan anahtarları kullanarak çeşitli istemciler, yazma çakışması olmadan aynı anda aynı konuma alt öğe ekleyebilir. push()
tarafından oluşturulan benzersiz anahtar, bir zaman damgasına dayanır. Bu nedenle liste öğeleri otomatik olarak kronolojik olarak sıralanır.
Alt öğenin otomatik olarak oluşturulan anahtarının değerini almak veya alt öğe için veri ayarlamak üzere push()
yöntemi tarafından döndürülen yeni verilere referans verebilirsiniz. push()
referansında getKey()
çağrısı yapıldığında otomatik olarak oluşturulan anahtarın değeri döndürülür.
Veri yapınızı düzleştirmeyi kolaylaştırmak için bu otomatik olarak oluşturulan anahtarları kullanabilirsiniz. Daha fazla bilgi için veri dağıtma örneğine bakın.
Alt etkinlikleri dinleme
Uygulamanız, listelerle çalışırken tek nesneler için kullanılan değer etkinlikleri yerine alt etkinlikleri dinlemelidir.
Alt öğe etkinlikleri, bir işlemden kaynaklanan belirli işlemlere (ör. push()
yöntemi aracılığıyla eklenen yeni bir alt öğe veya updateChildren()
yöntemi aracılığıyla güncellenen bir alt öğe) yanıt olarak tetiklenir.
Bunların her biri, bir veritabanında belirli bir düğümde yapılan değişiklikleri dinlemek için yararlı olabilir.
DatabaseReference
'te alt etkinlikleri dinlemek için ChildEventListener
ekleyin:
Dinleyici | Etkinlik geri araması | Tipik kullanım |
---|---|---|
ChildEventListener
| onChildAdded() |
Öğe listelerini alma veya öğe listesine eklenen öğeleri dinleme
Bu geri çağırma, mevcut her alt öğe için bir kez ve ardından belirtilen yola her yeni alt öğe eklendiğinde tekrar tetiklenir. Dinleyiciye iletilen DataSnapshot , yeni çocuğun verilerini içerir.
|
onChildChanged() |
Listedeki öğelerde yapılan değişiklikleri dinleme Bu etkinlik, alt düğümün alt öğelerinde yapılan değişiklikler de dahil olmak üzere bir alt düğüm değiştirildiğinde tetiklenir. Etkinlik dinleyicisine iletilen DataSnapshot , alt öğeyle ilgili güncellenmiş verileri içerir.
|
|
onChildRemoved() |
Bir listeden öğelerin kaldırılmasını dinleyin. Etkinlik geri çağırma işlevine iletilen DataSnapshot , kaldırılan alt öğenin verilerini içerir.
|
|
onChildMoved() |
Sıralı bir listedeki öğelerin sırasıyla ilgili değişiklikleri dinleyin.
Bu etkinlik, onChildChanged() callback'i alt öğenin yeniden sıralanmasına neden olan bir güncelleme tarafından tetiklendiğinde tetiklenir.
orderByChild veya orderByValue ile sıralanan verilerle kullanılır.
|
Örneğin, bir sosyal blog uygulaması, bir yayındaki yorumlardaki etkinliği izlemek için aşağıdaki gibi bu yöntemleri birlikte kullanabilir:
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)
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);
Değer etkinliklerini dinleme
Veri listelerini okumanın önerilen yolu ChildEventListener
kullanmak olsa da bir liste referansına ValueEventListener
eklemenin yararlı olduğu durumlar vardır.
Bir veri listesine ValueEventListener
ekleyerek veri listesinin tamamını tek bir DataSnapshot
olarak döndürebilirsiniz. Ardından, tek tek çocuklara erişmek için bu DataSnapshot
'yi döngü içinde kullanabilirsiniz.
Sorgu için yalnızca tek bir eşleşme olsa bile anlık görüntü bir liste olmaya devam eder. Yalnızca tek bir öğe içerir. Öğeye erişmek için sonucu döngü içinde incelemeniz gerekir:
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()) // ... } })
Java
// My top posts by number of stars myTopPostsQuery.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot dataSnapshot) { for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) { // TODO: handle the post } } @Override public void onCancelled(@NonNull DatabaseError databaseError) { // Getting Post failed, log a message Log.w(TAG, "loadPost:onCancelled", databaseError.toException()); // ... } });
Bu kalıp, ek onChildAdded
etkinlikleri dinlemek yerine bir listenin tüm alt öğelerini tek bir işlemde almak istediğinizde yararlı olabilir.
Dinleyicileri kaldırma
Geri çağırma işlevleri, Firebase veritabanı referansınızda removeEventListener()
yöntemi çağrılarak kaldırılır.
Bir dinleyici bir veri konumuna birden çok kez eklendiyse her etkinlik için birden çok kez çağrılır ve tamamen kaldırmak için aynı sayıda kez ayırmanız gerekir.
Üst dinleyicide removeEventListener()
çağrıldığında, alt düğümlerine kayıtlı dinleyiciler otomatik olarak kaldırılmaz. Geri çağırma işlevinin kaldırılması için removeEventListener()
, alt dinleyicilerde de çağrılmalıdır.
Verileri sıralama ve filtreleme
Anahtara, değere veya bir alt öğenin değerine göre sıralanmış verileri almak için Realtime Database Query
sınıfını kullanabilirsiniz. Sıralı sonucu belirli bir sonuç sayısına veya anahtar ya da değer aralığına göre de filtreleyebilirsiniz.
Verileri sıralama
Sıralı verileri almak için sonuçların nasıl sıralandığını belirlemek üzere sıralama yöntemlerinden birini belirterek başlayın:
Yöntem | Kullanım |
---|---|
orderByChild() |
Sonuçları, belirtilen bir alt anahtarın veya iç içe yerleştirilmiş alt yolun değerine göre sıralayın. |
orderByKey()
| Sonuçları alt anahtarlara göre sıralayın. |
orderByValue() |
Sonuçları alt öğe değerlerine göre sıralayın. |
Aynı anda yalnızca bir sıralama yöntemi kullanabilirsiniz. Sıralama yönteminin aynı sorgu içinde birden çok kez çağrılması hata verir.
Aşağıdaki örnekte, bir kullanıcının yıldız sayısına göre sıralanmış en popüler gönderilerinin listesini nasıl alabileceğiniz gösterilmektedir:
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 // ... })
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 // ... });
Bu, bir alt dinleyici ile birlikte kullanıldığında istemciyi, kullanıcı kimliğine göre veritabanındaki yoldan kullanıcının gönderileriyle senkronize eden ve her gönderinin aldığı yıldız sayısına göre sıralayan bir sorgu tanımlar. Kimlikleri dizin anahtarı olarak kullanma tekniğine veri dağıtımı denir. Bu konu hakkında daha fazla bilgiyi Veritabanınızı Yapılandırma başlıklı makalede bulabilirsiniz.
orderByChild()
yönteminin çağrısı, sonuçların sıralanacağı alt anahtarı belirtir. Bu durumda, yayınlar ilgili "starCount"
alt öğesinin değerine göre sıralanır. Sorgular, aşağıdaki gibi verilere sahip olmanız durumunda iç içe yerleştirilmiş alt öğelere göre de sıralanabilir:
"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", } },
Bu örnekte, orderByChild()
çağrımızda iç içe yerleştirilmiş alt öğenin göreli yolunu belirterek liste öğelerimizi metrics
anahtarının altına yerleştirilmiş değerlere göre sıralayabiliriz.
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 // ... })
Java
// Most viewed posts Query myMostViewedPostsQuery = databaseReference.child("posts") .orderByChild("metrics/views"); myMostViewedPostsQuery.addChildEventListener(new ChildEventListener() { // TODO: implement the ChildEventListener methods as documented above // ... });
Diğer veri türlerinin nasıl sıralandığı hakkında daha fazla bilgi için Sorgu verileri nasıl sıralanır? başlıklı makaleyi inceleyin.
Veri filtreleme
Verileri filtrelemek için sorgu oluştururken sınır veya aralık yöntemlerinden herhangi birini bir sıralama yöntemiyle birleştirebilirsiniz.
Yöntem | Kullanım |
---|---|
limitToFirst() |
Sıralı sonuç listesinin başından döndürülecek maksimum öğe sayısını belirler. |
limitToLast() |
Sıralı sonuç listesinin sonundan döndürülecek maksimum öğe sayısını belirler. |
startAt() |
Seçilen sıralama yöntemine bağlı olarak, belirtilen anahtar veya değerden büyük ya da bu değere eşit öğeleri döndürme |
startAfter() |
Seçilen sıralama yöntemine bağlı olarak, belirtilen anahtar veya değerden büyük öğeleri döndürme |
endAt() |
Seçilen sıralama yöntemine bağlı olarak, belirtilen anahtar veya değerden düşük ya da ona eşit öğeleri döndürme |
endBefore() |
Seçilen sıralama yöntemine bağlı olarak, belirtilen anahtar veya değerden düşük öğeleri döndürme |
equalTo() |
Seçilen sıralama yöntemine bağlı olarak, belirtilen anahtara veya değere eşit öğeleri döndürme |
Sıralama yöntemlerinin aksine, birden fazla sınır veya aralık işlevini birleştirebilirsiniz.
Örneğin, sonuçları belirli bir değer aralığına sınırlamak için startAt()
ve endAt()
yöntemlerini birleştirebilirsiniz.
Sorgu için yalnızca tek bir eşleşme olsa bile anlık görüntü bir liste olmaya devam eder. Yalnızca tek bir öğe içerir. Öğeye erişmek için sonucu döngü içinde incelemeniz gerekir:
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()) // ... } })
Java
// My top posts by number of stars myTopPostsQuery.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot dataSnapshot) { for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) { // TODO: handle the post } } @Override public void onCancelled(@NonNull DatabaseError databaseError) { // Getting Post failed, log a message Log.w(TAG, "loadPost:onCancelled", databaseError.toException()); // ... } });
Sonuç sayısını sınırlama
Belirli bir geri çağırma için senkronize edilecek maksimum çocuk sayısını ayarlamak üzere limitToFirst()
ve limitToLast()
yöntemlerini kullanabilirsiniz. Örneğin, 100 sınırı belirlemek için limitToFirst()
kullanırsanız başlangıçta yalnızca 100'e kadar onChildAdded()
geri çağırma alırsınız. Firebase veritabanınızda 100'den az öğe depolanıyorsa her öğe için bir onChildAdded()
geri çağırma işlevi tetiklenir.
Öğeler değiştikçe, toplam sayının 100'de kalması için sorguya giren öğeler için onChildAdded()
geri çağırma ve sorgudan çıkan öğeler için onChildRemoved()
geri çağırma alırsınız.
Aşağıdaki örnekte, örnek blog uygulamasının tüm kullanıcıların en son 100 yayınının listesini almak için nasıl sorgu tanımladığı gösterilmektedir:
Kotlin+KTX
// Last 100 posts, these are automatically the 100 most recent // due to sorting by push() keys. databaseReference.child("posts").limitToFirst(100)
Java
// Last 100 posts, these are automatically the 100 most recent // due to sorting by push() keys Query recentPostsQuery = databaseReference.child("posts") .limitToFirst(100);
Bu örnekte yalnızca bir sorgu tanımlanmaktadır. Verileri senkronize etmek için bağlı bir dinleyici olması gerekir.
Anahtara veya değere göre filtreleme
Sorgular için rastgele başlangıç, bitiş ve eşdeğerlik noktaları seçmek üzere startAt()
, startAfter()
, endAt()
, endBefore()
ve equalTo()
kullanabilirsiniz. Bu, verileri sayfalara ayırmak veya belirli bir değere sahip alt öğeleri olan öğeleri bulmak için yararlı olabilir.
Sorgu verilerinin sıralama şekli
Bu bölümde, verilerin Query
sınıfındaki sıralama yöntemlerine göre nasıl sıralandığı açıklanmaktadır.
orderByChild
orderByChild()
kullanıldığında, belirtilen alt anahtarı içeren veriler aşağıdaki gibi sıralanır:
- Belirtilen alt anahtar için
null
değerine sahip alt öğeler önce gelir. - Ardından, belirtilen alt anahtar için
false
değerine sahip alt öğeler gelir. Birden fazla çocuğun değerifalse
ise anahtara göre alfabetik olarak sıralanır. - Ardından, belirtilen alt anahtar için
true
değerine sahip alt öğeler gelir. Birden fazla alt öğenin değeritrue
ise bu öğeler anahtara göre alfabetik olarak sıralanır. - Ardından, sayısal değere sahip alt öğeler artan düzende sıralanır. Belirtilen alt öğe düğümü için birden fazla alt öğenin sayısal değeri aynıysa bu öğeler anahtara göre sıralanır.
- Dizelerin sırası, sayılardan sonra gelir ve alfabetik olarak artan düzendedir. Belirtilen alt öğe düğümü için birden fazla alt öğe aynı değere sahipse bu öğeler anahtara göre alfabetik olarak sıralanır.
- Nesneler en son gelir ve anahtara göre artan düzende alfabetik olarak sıralanır.
orderByKey
Verilerinizi sıralamak için orderByKey()
kullanıldığında veriler, anahtara göre artan düzende döndürülür.
- 32 bitlik tam sayı olarak ayrıştırılabilen bir anahtara sahip alt öğeler önce gelir ve artan düzende sıralanır.
- Anahtarı dize değeri olan alt öğeler, artan sözlük sırasına göre sıralanır.
orderByValue
orderByValue()
kullanılırken alt öğeler değerlerine göre sıralanır. Sıralama ölçütleri, belirtilen alt anahtarın değeri yerine düğümün değeri kullanıldığı dışında orderByChild()
ile aynıdır.