Android'de Veri Listeleri ile Çalışma

Bu doküman, Firebase'deki veri listeleriyle çalışmayı kapsar. Firebase verilerini okuma ve yazmayla ilgili temel bilgileri inceleyin Android'de Veri Okuma ve Yazma

DatabaseReference alma

Veritabanından veri okumak ve yazmak için bir 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();

Liste okuma ve yazma

Veri listesine ekle

Ç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. Bu araçları kullanarak her yeni öğe için otomatik olarak oluşturulan anahtarlara sahip olduğundan, bazı müşteriler yazma çakışmaları olmadan aynı anda aynı konuma alt öğe ekleme. İlgili içeriği oluşturmak için kullanılan push() tarafından oluşturulan benzersiz anahtar bir zaman damgasına dayalı olduğundan liste öğeleri kronolojik olarak otomatik olarak sıralanır.

Aşağıdakileri almak için push() yönteminin döndürdüğü yeni verilere referansı kullanabilirsiniz. alt yayıncının otomatik olarak oluşturduğu anahtarın değerini veya çocuk için veri ayarlayın. Telefon etme push() referansındaki getKey(), otomatik olarak oluşturulan anahtardır.

Verilerinizi birleştirmeyi kolaylaştırmak için otomatik olarak oluşturulan bu anahtarları kullanabilirsiniz inceleyeceğiz. Daha fazla bilgi için veri yayma işlemini inceleyin example) arayın.

Çocuk etkinliklerini dinle

Listelerle çalışırken uygulamanız alt etkinlikleri dinlemelidir tek nesneler için kullanılan değer etkinlikleri yerine

Alt etkinlikler, Bir işlemdeki düğümün alt öğeleridir (ör. push() yöntemi veya updateChildren() yöntemiyle güncellenen bir alt öğe. Bunların her biri, bir veritabanında belirli bir düğümde yapılan değişiklikleri dinlemek için yararlı olabilir.

DatabaseReference uygulamasında alt etkinlikleri dinlemek için bir ChildEventListener:

Dinleyici Etkinlik geri çağırması 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. İşleyiciye iletilen DataSnapshot, yeni çocuğun verileri.
onChildChanged() Listedeki öğelerde yapılan değişiklikleri dinleme Bu etkinlik herhangi bir zamanda alt düğümünün, alt öğelerinde yapılan tüm değişiklikler dahil olmak üzere değiştirildiğinde alt düğüm. DataSnapshot, etkinliğe geçti işleyici, çocuk için güncellenmiş verileri içerir.
onChildRemoved() Bir listeden kaldırılan öğeleri bekleyin. İlgili içeriği oluşturmak için kullanılan Etkinlik geri çağırmasına iletilen DataSnapshot, verileri geri yüklenir.
onChildMoved() Sıralı listedeki öğelerin sırasındaki değişiklikleri bekleyin. Bu etkinlik, onChildChanged() geri çağırma, alt öğenin yeniden sıralanmasına neden olan bir güncelleme tarafından tetiklenir. orderByChild veya orderByValue ile sıralanan verilerle kullanılır.

Örneğin, bir sosyal blog uygulaması bu yöntemleri kullanabilir aşağıdaki gibi bir gönderinin yorumlarındaki etkinliği izlemek için aşağıdaki adımları uygulayın:

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 etkinliklerine göz atın

Ancak ChildEventListener kullanmak Bazı durumlarda listeye ValueEventListener ekleyebilirsiniz. bu da faydalı olacaktı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 tek bir eşleşme olsa bile anlık görüntü yine de listele: tek bir öğe içeriyor. Öğ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, bir listenin tüm alt öğelerini getirmek istediğinizde yararlı olabilir ek onChildAdded dinlemek yerine tek bir işlemde etkinlikler.

Dinleyicileri ayır

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.

Ebeveyn dinleyicide removeEventListener() adlı kullanıcıya yapılan arama şunu yapmaz: alt düğümlerine kayıtlı işleyicileri otomatik olarak kaldırmalıdır; removeEventListener(), tüm çocuk dinleyicilerde de çağrılmalıdır tuşuna basarak geri çağırmayı kaldırın.

Verileri sıralama ve filtreleme

Verileri sıralama ölçütü olarak almak için Realtime Database Query sınıfını kullanabilirsiniz değerine veya bir alt öğe değerine göre düzenleyebilirsiniz. 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ıralanmış verileri almak için öncelikle sıralamaya göre yöntemlerden birini belirterek sonuçların nasıl sıralandığını belirler:

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. Tek tek sıralama yöntemini çağırma işlemi birden çok kez tekrarlanırsa 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 işleyici ile birleştirildiğinde sorguyu tanımlar istemciyi, veritabanındaki yoldaki kullanıcının yayınlarıyla senkronize eder kullanıcı kimliklerine göre, her yayının aldığı yıldız sayısına göre sıralanır. Kimlikleri dizin anahtarı olarak kullanma tekniğine veri dağıtımı denir. Bu konu hakkında daha fazla bilgiyi Veri Tabanı Oluşturma başlıklı makalede bulabilirsiniz.

orderByChild() yöntemine yapılan çağrı, arama sonuçlarını görebilirsiniz. Bu durumda, yayınlar ilgili yayınların değerine göre, "starCount" çocuk. Sorgular, iç içe yerleştirilmiş ya da çocuklarınız (örneğin, aşağıdaki gibi görünen verileriniz varsa):

"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, liste öğelerimizi metrics anahtarı için, iç içe yerleştirilmiş alt öğenin göreli yolunu orderByChild() arama.

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 verilerinin sıralanma şekli.

Veri filtreleme

Verileri filtrelemek için sınır veya aralık yöntemlerinden herhangi birini, yönteme göre sırala.

Yöntem Kullanım
limitToFirst() Döndürülecek maksimum öğe sayısını sıralı sonuç listesi.
limitToLast() Siparişin sonundan itibaren iade edilecek maksimum öğe sayısını ayarlar sonuç listesi.
startAt() Belirtilen anahtar veya değerden büyük veya ona eşit olan öğeleri döndür seçilen yönteme göre değişir.
startAfter() Belirtilen anahtar veya değerden büyük öğeleri döndür seçilen yönteme göre değişir.
endAt() Belirtilen anahtar veya değerden düşük veya ona eşit öğeleri döndür seçilen yönteme göre değişir.
endBefore() Belirtilen anahtar veya değerden daha düşük olan öğeleri döndür seçilen yönteme göre değişir.
equalTo() Belirtilen anahtara veya değere eşit olan öğeleri döndür seçilen yönteme göre değişir.

Sıralama ölçütü yöntemlerinden farklı olarak birden çok sınırlama 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 tek bir eşleşme olsa bile anlık görüntü hâlâ bir liste, tek bir öğe içeriyor. Öğeye erişmek için gerekenler döngüyü yapmak için:

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ırlandırın

limitToFirst() ve limitToLast() yöntemlerini kullanarak belirli bir geri çağırma için senkronize edilecek maksimum alt öğe sayısı. Örneğin, 100'lük bir sınır belirlemek için limitToFirst() kullanıyorsanız başlangıçta yalnızca en fazla 100 onChildAdded() geri arama. Hesabınızda depoladığınız öğe sayısı 100'den azsa Firebase veritabanını kullanıyorsanız her öğe için bir onChildAdded() geri çağırması 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 bir sorguyu tüm kullanıcılar tarafından paylaşılan en son 100 yayının listesini al:

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 ve yalnızca Ekte bir dinleyici bulunmalıdır.

Anahtar veya değere göre filtreleyin

startAt(), startAfter(), endAt(), endBefore() ve kullanabilirsiniz equalTo() için rastgele başlangıç, bitiş ve denklik noktaları seçin daha fazla bilgi edineceksiniz. Bu, verileri sayfalara ayırmak veya çocukların bulunduğu öğeleri bulmak için yararlı olabilir reklam grubudur.

Sorgu verilerinin sıralama şekli

Bu bölümde, verilerin her bir yönteme göre nasıl sıralandığı açıklanmaktadır. Query sınıf.

orderByChild

orderByChild() kullanılırken belirtilen alt anahtarı içeren veriler şu şekilde sıralanmıştır:

  1. Belirtilen alt anahtar için null değerine sahip alt öğeler gelir tıklayın.
  2. Belirtilen alt anahtar için false değerine sahip alt öğeler bir sonraki adımımız var. Birden fazla çocuk false değerine sahipse anahtara göre sözlüksel olarak sıralanır.
  3. Belirtilen alt anahtar için true değerine sahip alt öğeler bir sonraki adımımız var. Birden fazla çocuk true değerine sahipse anahtar kelimelere göre sıralanması.
  4. Sayısal değere sahip olan 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.
  5. Dizeler sayılardan sonra gelir ve sözlüksel olarak artan düzende sıralanır. sipariş. Belirtilen alt öğe için aynı değere sahip birden fazla alt öğe varsa bu terimler sözlüksel olarak anahtara göre sıralanır.
  6. Nesneler son sırada gelir ve anahtara göre sözlüksel olarak artan düzende sıralanır.

orderByKey

Verilerinizi sıralamak için orderByKey() kullandığınızda veriler artan düzende döndürülür anahtara göre.

  1. 32 bitlik tam sayı olarak ayrıştırılabilen bir anahtara sahip alt öğeler önce gelir ve artan düzende sıralanır.
  2. Anahtarlarında dize değeri olan alt öğeler sıradaki sırayla, sözlüksel olarak artan düzende 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.

Sonraki adımlar