Bu belge, Firebase'deki veri listeleriyle çalışmayı kapsar. Firebase verilerini okuma ve yazmanın temellerini öğrenmek için bkz. Android'de Veri Okuma ve Yazma .
Veritabanı Referansı Alın
Veritabanından 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 alt öğe eklendiğinde benzersiz bir anahtar oluşturur. Listedeki her yeni öğe için otomatik olarak oluşturulan bu anahtarları kullanarak, birkaç istemci, yazma çakışmaları olmadan aynı anda aynı konuma alt öğeler ekleyebilir. push()
tarafından oluşturulan benzersiz anahtar bir zaman damgasını temel alır, dolayısıyla liste öğeleri otomatik olarak kronolojik olarak sıralanır.
Alt öğenin otomatik olarak oluşturulan anahtarının değerini veya alt öğe için ayarlanan verileri almak için push()
yöntemi tarafından döndürülen yeni verilere yapılan başvuruyu kullanabilirsiniz. Bir push()
referansında getKey()
işlevinin çağrılması, otomatik olarak oluşturulan anahtarın değerini döndürür.
Veri yapınızı düzleştirmeyi kolaylaştırmak için otomatik olarak oluşturulan bu anahtarları kullanabilirsiniz. Daha fazla bilgi için veri yayma örneğine bakın.
Alt etkinlikleri dinle
Listelerle çalışırken uygulamanız, tek nesneler için kullanılan değer olayları yerine alt olayları dinlemelidir.
Alt olaylar, push()
yöntemi aracılığıyla eklenen yeni bir alt öğe veya updateChildren()
yöntemi aracılığıyla güncellenen bir alt öğe gibi bir işlemden bir düğümün alt öğelerinin başına gelen belirli işlemlere yanıt olarak tetiklenir. Bunların her biri bir veritabanındaki belirli bir düğümde yapılan değişiklikleri dinlemek için yararlı olabilir.
DatabaseReference
alt olayları dinlemek için bir ChildEventListener
ekleyin:
Dinleyici | Olay geri araması | Tipik kullanım |
---|---|---|
ChildEventListener | onChildAdded() | Öğe listelerini alın veya öğe listesine yapılan eklemeleri dinleyin. 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 alt öğenin verilerini içerir. |
onChildChanged() | Listedeki öğelerde yapılan değişiklikleri dinleyin. Bu olay, alt düğümün alt öğelerinde yapılan değişiklikler de dahil olmak üzere, bir alt düğüm değiştirildiğinde her zaman tetiklenir. Olay dinleyicisine iletilen DataSnapshot alt öğe için güncelleştirilmiş verileri içerir. | |
onChildRemoved() | Listeden kaldırılan öğeleri dinleyin. Olay geri çağrısına iletilen DataSnapshot kaldırılan alt öğeye ilişkin verileri içerir. | |
onChildMoved() | Sıralı bir listedeki öğelerin sırasındaki değişiklikleri dinleyin. Bu olay, alt öğenin yeniden sıralanmasına neden olan bir güncelleme tarafından onChildChanged() geri çağrısı tetiklendiğinde tetiklenir. orderByChild veya orderByValue ile sıralanan verilerle kullanılır. |
Örneğin, bir sosyal blog uygulaması, aşağıda gösterildiği gibi bir gönderinin yorumlarındaki etkinliği izlemek için 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 olaylarını dinleyin
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
eklemek, tüm veri listesini tek bir DataSnapshot
olarak döndürür; daha sonra tek tek alt öğelere erişmek için bunları döngüleyebilirsiniz.
Sorgu için yalnızca tek bir eşleşme olsa bile anlık görüntü hâlâ bir listedir; yalnızca tek bir öğe içerir. Öğeye erişmek için sonucun üzerinden geçmeniz 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 model, ek onChildAdded
olaylarını dinlemek yerine, bir listenin tüm alt öğelerini tek bir işlemle getirmek istediğinizde yararlı olabilir.
Dinleyicileri ayırın
Geri aramalar, Firebase veritabanı referansınızda removeEventListener()
yöntemi çağrılarak kaldırılır.
Bir dinleyici bir veri konumuna birden çok kez eklenmişse, her olay için birden çok kez çağrılır ve onu tamamen kaldırmak için aynı sayıda ayırmanız gerekir.
Bir üst dinleyicide removeEventListener()
işlevinin çağrılması, alt düğümlerinde kayıtlı dinleyicileri otomatik olarak kaldırmaz; Geri çağırmayı kaldırmak için herhangi bir alt dinleyicide de removeEventListener()
ç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 Gerçek Zamanlı Veritabanı Query
sınıfını kullanabilirsiniz. Ayrıca sıralanan sonucu belirli sayıda sonuca veya bir anahtar veya değer aralığına göre filtreleyebilirsiniz.
Verileri sırala
Sıralanmış verileri almak için, sonuçların nasıl sıralanacağını belirlemek üzere sıralama yöntemlerinden birini belirterek başlayın:
Yöntem | Kullanım |
---|---|
orderByChild() | Sonuçları belirtilen alt anahtarın veya iç içe geçmiş alt yolun değerine göre sıralayın. | orderByKey() | Sonuçları alt anahtarlara göre sıralayın. |
orderByValue() | Sonuçları alt değerlere göre sıralayın. |
Aynı anda yalnızca tek bir sipariş yöntemi kullanabilirsiniz. Aynı sorguda bir sıralama yöntemini birden çok kez çağırmak hataya neden olur.
Aşağıdaki örnek, bir kullanıcının yıldız sayısına göre sıralanmış en iyi gönderilerinin listesini nasıl alabileceğinizi gösterir:
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 dinleyiciyle birleştirildiğinde, istemciyi, kullanıcı kimliğine dayalı olarak, her gönderinin aldığı yıldız sayısına göre sıralanmış olarak, veritabanındaki yoldan kullanıcının gönderileriyle senkronize eden bir sorguyu tanımlar. Kimlikleri dizin anahtarları olarak kullanma tekniğine veri yayma adı verilir; bu konuda daha fazla bilgiyi Veritabanınızı Yapılandırma bölümünde okuyabilirsiniz.
orderByChild()
yöntemine yapılan çağrı, sonuçların sıralanacağı alt anahtarı belirtir. Bu durumda gönderiler ilgili "starCount"
alt öğelerinin değerine göre sıralanır. Şuna benzer verileriniz olması durumunda, sorgular iç içe geçmiş çocuklara 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 geçmiş alt öğenin göreceli yolunu belirterek, liste öğelerimizi metrics
anahtarının altında yuvalanmış 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 bkz . Sorgu verileri nasıl sıralanır ?
Verileri filtreleme
Verileri filtrelemek için, sorgu oluştururken limit veya aralık yöntemlerinden herhangi birini sıralama yöntemiyle birleştirebilirsiniz.
Yöntem | Kullanım |
---|---|
limitToFirst() | Sıralı sonuç listesinin başından itibaren döndürülecek maksimum öğe sayısını ayarlar. |
limitToLast() | Sıralı sonuç listesinin sonundan döndürülecek maksimum öğe sayısını ayarlar. |
startAt() | Seçilen sıralama yöntemine bağlı olarak, belirtilen anahtara veya değere eşit veya ondan büyük öğeleri döndürün. |
startAfter() | Seçilen sıralama yöntemine bağlı olarak, belirtilen anahtar veya değerden daha büyük öğeleri döndürün. |
endAt() | Seçilen sıralama yöntemine bağlı olarak, belirtilen anahtara veya değere eşit veya ondan küçük öğeleri döndürün. |
endBefore() | Seçilen sıralama yöntemine bağlı olarak, belirtilen anahtar veya değerden daha az olan öğeleri döndürün. |
equalTo() | Seçilen sıralama yöntemine bağlı olarak, belirtilen anahtara veya değere eşit öğeleri döndürün. |
Sıralama yöntemlerinden farklı olarak birden fazla limit veya aralık fonksiyonunu birleştirebilirsiniz. Örneğin, sonuçları belirli bir değer aralığıyla 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ü hâlâ bir listedir; yalnızca tek bir öğe içerir. Öğeye erişmek için sonucun üzerinden geçmeniz 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ırlayın
Belirli bir geri arama için senkronize edilecek maksimum alt çocuk sayısını ayarlamak için limitToFirst()
ve limitToLast()
yöntemlerini kullanabilirsiniz. Örneğin, limitToFirst()
yöntemini 100'lük bir sınır ayarlamak için kullanırsanız, başlangıçta yalnızca 100'e kadar onChildAdded()
geri araması alırsınız. Firebase veritabanınızda depolanan öğe sayısı 100'den azsa her öğe için bir onChildAdded()
geri çağrısı tetiklenir.
Öğeler değiştikçe, sorguya giren öğeler için onChildAdded()
geri çağrılarını ve sorgudan çıkan öğeler için onChildRemoved()
geri çağrılarını alırsınız; böylece toplam sayı 100'de kalır.
Aşağıdaki örnek, örnek blog uygulamasının, tüm kullanıcıların en son 100 gönderisinin listesini almak için bir sorguyu nasıl tanımladığını gösterir:
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 örnek yalnızca bir sorguyu tanımlar; verileri senkronize etmek için bir dinleyicinin eklenmesi gerekir.
Anahtar veya değere göre filtrele
Sorgular için rastgele başlangıç, bitiş ve eşdeğerlik noktaları seçmek amacıyla startAt()
, startAfter()
endAt()
, endBefore()
ve equalTo()
kullanabilirsiniz. Bu, verileri sayfalara ayırmak veya belirli bir değere sahip alt öğelerin bulunduğu öğeleri bulmak için yararlı olabilir.
Sorgu verileri nasıl sıralanır?
Bu bölümde verilerin Query
sınıfındaki sıralama yöntemlerinin her birine göre nasıl sıralandığı açıklanmaktadır.
orderByChild
orderByChild()
kullanıldığında, belirtilen alt anahtarı içeren veriler şu şekilde sıralanır:
- Belirtilen alt anahtar için
null
değeri olan çocuklar önce gelir. - Daha sonra belirtilen alt anahtar için
false
değerine sahip çocuklar gelir. Birden fazla çocuğunfalse
değeri varsa, bunlar sözlüksel olarak anahtara göre sıralanır. - Daha sonra belirtilen alt anahtar için
true
değeri olan çocuklar gelir. Birden fazla çocuğuntrue
değeri varsa, bunlar sözlüksel olarak anahtara göre sıralanır. - Daha sonra sayısal değeri olan çocuklar artan düzende sıralanarak gelir. Birden fazla alt öğe, belirtilen alt düğüm için aynı sayısal değere sahipse anahtara göre sıralanır.
- Dizeler sayılardan sonra gelir ve sözlükbilimsel olarak artan düzende sıralanır. Belirtilen alt düğüm için birden fazla alt öğe aynı değere sahipse, bunlar sözlüksel olarak anahtara göre sıralanır.
- Nesneler en sonda gelir ve sözlükbilimsel olarak anahtara göre artan düzende sıralanır.
orderByKey
Verilerinizi sıralamak için orderByKey()
kullanıldığında, veriler anahtara göre artan sırada döndürülür.
- 32 bitlik bir tamsayı olarak ayrıştırılabilen bir anahtarı olan çocuklar, artan düzende sıralanarak önce gelir.
- Anahtarları dize değeri olan çocuklar daha sonra sözlükbilimsel olarak artan düzende sıralanır.
orderByValue
orderByValue()
kullanıldığında, çocuklar değerlerine göre sıralanır. Sıralama kriterleri, belirtilen alt anahtarın değeri yerine düğümün değerinin kullanılması dışında orderByChild()
ile aynıdır.