Ikuti semua informasi yang diumumkan di Firebase Summit, dan pelajari bagaimana Firebase dapat membantu Anda mempercepat pengembangan aplikasi dan menjalankan aplikasi dengan percaya diri. Pelajari Lebih Lanjut

Mengambil Data

Tetap teratur dengan koleksi Simpan dan kategorikan konten berdasarkan preferensi Anda.

Dokumen ini mencakup dasar-dasar pengambilan data database, cara data diurutkan, dan cara melakukan kueri sederhana pada data. Pengambilan data di Admin SDK diterapkan sedikit berbeda di berbagai bahasa pemrograman.

  1. Listener asinkron: Data yang disimpan di Firebase Realtime Database diambil dengan melampirkan listener asinkron ke referensi database. Listener dipicu sekali untuk status awal data dan sekali lagi kapan saja data berubah. Seorang pendengar acara dapat menerima beberapa jenis acara yang berbeda. Mode pengambilan data ini didukung di Java, Node.js, dan Python Admin SDK.
  2. Pemblokiran berbunyi: Data yang disimpan di Firebase Realtime Database diambil dengan menggunakan metode pemblokiran pada referensi database, yang mengembalikan data yang disimpan di referensi. Setiap pemanggilan metode adalah operasi satu kali. Itu berarti SDK tidak mendaftarkan callback apa pun yang mendengarkan pembaruan data berikutnya. Model pengambilan data ini didukung di Python dan Go Admin SDK.

Mulai

Mari kita lihat kembali contoh blogging dari artikel sebelumnya untuk memahami cara membaca data dari database Firebase. Ingat bahwa posting blog di aplikasi contoh disimpan di URL database https://docs-examples.firebaseio.com/server/saving-data/fireblog/posts.json . Untuk membaca data posting Anda, Anda dapat melakukan hal berikut:

Jawa
public static class Post {

  public String author;
  public String title;

  public Post(String author, String title) {
    // ...
  }

}

// Get a reference to our posts
final FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference ref = database.getReference("server/saving-data/fireblog/posts");

// Attach a listener to read the data at our posts reference
ref.addValueEventListener(new ValueEventListener() {
  @Override
  public void onDataChange(DataSnapshot dataSnapshot) {
    Post post = dataSnapshot.getValue(Post.class);
    System.out.println(post);
  }

  @Override
  public void onCancelled(DatabaseError databaseError) {
    System.out.println("The read failed: " + databaseError.getCode());
  }
});
Node.js
// Get a database reference to our posts
const db = getDatabase();
const ref = db.ref('server/saving-data/fireblog/posts');

// Attach an asynchronous callback to read the data at our posts reference
ref.on('value', (snapshot) => {
  console.log(snapshot.val());
}, (errorObject) => {
  console.log('The read failed: ' + errorObject.name);
}); 
Python
# Import database module.
from firebase_admin import db

# Get a database reference to our posts
ref = db.reference('server/saving-data/fireblog/posts')

# Read the data at the posts reference (this is a blocking operation)
print(ref.get())
Pergi

// Post is a json-serializable type.
type Post struct {
	Author string `json:"author,omitempty"`
	Title  string `json:"title,omitempty"`
}

// Create a database client from App.
client, err := app.Database(ctx)
if err != nil {
	log.Fatalln("Error initializing database client:", err)
}

// Get a database reference to our posts
ref := client.NewRef("server/saving-data/fireblog/posts")

// Read the data at the posts reference (this is a blocking operation)
var post Post
if err := ref.Get(ctx, &post); err != nil {
	log.Fatalln("Error reading value:", err)
}

Jika Anda menjalankan kode di atas, Anda akan melihat objek yang berisi semua posting Anda yang masuk ke konsol. Dalam kasus Node.js dan Java, fungsi listener dipanggil setiap kali data baru ditambahkan ke referensi database Anda, dan Anda tidak perlu menulis kode tambahan untuk mewujudkannya.

Di Java dan Node.js, fungsi callback menerima DataSnapshot , yang merupakan snapshot data. Snapshot adalah gambar data pada referensi database tertentu pada satu titik waktu. Memanggil val() / getValue() pada snapshot mengembalikan representasi objek bahasa tertentu dari data. Jika tidak ada data di lokasi referensi, nilai snapshot adalah null . Metode get() dalam Python mengembalikan representasi Python dari data secara langsung. Fungsi Get() di Go memisahkan data ke dalam struktur data tertentu.

Perhatikan bahwa kami menggunakan tipe peristiwa value dalam contoh di atas, yang membaca seluruh konten referensi database Firebase, meskipun hanya satu bagian data yang diubah. value adalah salah satu dari lima jenis peristiwa berbeda yang tercantum di bawah ini yang dapat Anda gunakan untuk membaca data dari database.

Baca Jenis Acara di Java dan Node.js

Nilai

Peristiwa value digunakan untuk membaca snapshot statis dari konten pada jalur database tertentu, seperti yang ada pada saat peristiwa baca. Ini dipicu sekali dengan data awal dan lagi setiap kali data berubah. Callback peristiwa melewati snapshot yang berisi semua data di lokasi itu, termasuk data turunan. Dalam contoh kode di atas, value mengembalikan semua entri blog di aplikasi Anda. Setiap kali posting blog baru ditambahkan, fungsi panggilan balik akan mengembalikan semua posting.

Anak Ditambahkan

Acara child_added biasanya digunakan saat mengambil daftar item dari database. Tidak seperti value yang mengembalikan seluruh konten lokasi, child_added dipicu sekali untuk setiap anak yang ada dan kemudian lagi setiap kali anak baru ditambahkan ke jalur yang ditentukan. Panggilan balik acara diteruskan snapshot yang berisi data anak baru. Untuk tujuan pemesanan, itu juga melewati argumen kedua yang berisi kunci dari anak sebelumnya.

Jika Anda hanya ingin mengambil data pada setiap posting baru yang ditambahkan ke aplikasi blog Anda, Anda dapat menggunakan child_added :

Jawa
ref.addChildEventListener(new ChildEventListener() {
  @Override
  public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {
    Post newPost = dataSnapshot.getValue(Post.class);
    System.out.println("Author: " + newPost.author);
    System.out.println("Title: " + newPost.title);
    System.out.println("Previous Post ID: " + prevChildKey);
  }

  @Override
  public void onChildChanged(DataSnapshot dataSnapshot, String prevChildKey) {}

  @Override
  public void onChildRemoved(DataSnapshot dataSnapshot) {}

  @Override
  public void onChildMoved(DataSnapshot dataSnapshot, String prevChildKey) {}

  @Override
  public void onCancelled(DatabaseError databaseError) {}
});
Node.js
// Retrieve new posts as they are added to our database
ref.on('child_added', (snapshot, prevChildKey) => {
  const newPost = snapshot.val();
  console.log('Author: ' + newPost.author);
  console.log('Title: ' + newPost.title);
  console.log('Previous Post ID: ' + prevChildKey);
});

Dalam contoh ini snapshot akan berisi objek dengan posting blog individual. Karena SDK mengonversi postingan menjadi objek dengan mengambil nilainya, Anda memiliki akses ke properti penulis dan judul postingan dengan memanggil author dan title masing-masing. Anda juga memiliki akses ke ID posting sebelumnya dari argumen prevChildKey kedua.

Anak Berubah

Acara child_changed dipicu setiap kali node anak dimodifikasi. Ini termasuk modifikasi apa pun pada turunan dari simpul anak. Biasanya digunakan bersama dengan child_added dan child_removed untuk merespons perubahan pada daftar item. Cuplikan yang diteruskan ke panggilan balik peristiwa berisi data yang diperbarui untuk turunan.

Anda dapat menggunakan child_changed untuk membaca data yang diperbarui pada entri blog saat diedit:

Jawa
ref.addChildEventListener(new ChildEventListener() {
  @Override
  public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {}

  @Override
  public void onChildChanged(DataSnapshot dataSnapshot, String prevChildKey) {
    Post changedPost = dataSnapshot.getValue(Post.class);
    System.out.println("The updated post title is: " + changedPost.title);
  }

  @Override
  public void onChildRemoved(DataSnapshot dataSnapshot) {}

  @Override
  public void onChildMoved(DataSnapshot dataSnapshot, String prevChildKey) {}

  @Override
  public void onCancelled(DatabaseError databaseError) {}
});
Node.js
// Get the data on a post that has changed
ref.on('child_changed', (snapshot) => {
  const changedPost = snapshot.val();
  console.log('The updated post title is ' + changedPost.title);
});

Anak Dihapus

Acara child_removed dipicu saat anak langsung dihapus. Ini biasanya digunakan bersama dengan child_added dan child_changed . Cuplikan yang diteruskan ke panggilan balik peristiwa berisi data untuk turunan yang dihapus.

Dalam contoh blog, Anda dapat menggunakan child_removed untuk mencatat pemberitahuan tentang kiriman yang dihapus ke konsol:

Jawa
ref.addChildEventListener(new ChildEventListener() {
  @Override
  public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {}

  @Override
  public void onChildChanged(DataSnapshot dataSnapshot, String prevChildKey) {}

  @Override
  public void onChildRemoved(DataSnapshot dataSnapshot) {
    Post removedPost = dataSnapshot.getValue(Post.class);
    System.out.println("The blog post titled " + removedPost.title + " has been deleted");
  }

  @Override
  public void onChildMoved(DataSnapshot dataSnapshot, String prevChildKey) {}

  @Override
  public void onCancelled(DatabaseError databaseError) {}
});
Node.js
// Get a reference to our posts
const ref = db.ref('server/saving-data/fireblog/posts');

// Get the data on a post that has been removed
ref.on('child_removed', (snapshot) => {
  const deletedPost = snapshot.val();
  console.log('The blog post titled \'' + deletedPost.title + '\' has been deleted');
});

Anak Pindah

Peristiwa child_moved digunakan saat bekerja dengan data yang diurutkan, yang akan dibahas di bagian berikutnya .

Jaminan Acara

Basis data Firebase membuat beberapa jaminan penting terkait peristiwa:

Jaminan Acara Basis Data
Acara akan selalu dipicu saat status lokal berubah.
Peristiwa pada akhirnya akan selalu mencerminkan keadaan data yang benar, bahkan dalam kasus di mana operasi atau waktu lokal menyebabkan perbedaan sementara, seperti hilangnya koneksi jaringan untuk sementara.
Menulis dari satu klien akan selalu ditulis ke server dan disiarkan ke pengguna lain secara berurutan.
Peristiwa nilai selalu dipicu terakhir dan dijamin berisi pembaruan dari peristiwa lain yang terjadi sebelum cuplikan itu diambil.

Karena peristiwa nilai selalu dipicu terakhir, contoh berikut akan selalu berfungsi:

Jawa
final AtomicInteger count = new AtomicInteger();

ref.addChildEventListener(new ChildEventListener() {
  @Override
  public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {
    // New child added, increment count
    int newCount = count.incrementAndGet();
    System.out.println("Added " + dataSnapshot.getKey() + ", count is " + newCount);
  }

  // ...
});

// The number of children will always be equal to 'count' since the value of
// the dataSnapshot here will include every child_added event triggered before this point.
ref.addListenerForSingleValueEvent(new ValueEventListener() {
  @Override
  public void onDataChange(DataSnapshot dataSnapshot) {
    long numChildren = dataSnapshot.getChildrenCount();
    System.out.println(count.get() + " == " + numChildren);
  }

  @Override
  public void onCancelled(DatabaseError databaseError) {}
});
Node.js
let count = 0;

ref.on('child_added', (snap) => {
  count++;
  console.log('added:', snap.key);
});

// length will always equal count, since snap.val() will include every child_added event
// triggered before this point
ref.once('value', (snap) => {
  console.log('initial data loaded!', snap.numChildren() === count);
});

Melepaskan Panggilan Balik

Callback dihapus dengan menentukan jenis event dan fungsi callback yang akan dihapus, seperti berikut ini:

Jawa
// Create and attach listener
ValueEventListener listener = new ValueEventListener() {
    // ...
};
ref.addValueEventListener(listener);

// Remove listener
ref.removeEventListener(listener);
Node.js
ref.off('value', originalCallback);

Jika Anda meneruskan konteks cakupan ke on() , itu harus diteruskan saat melepaskan panggilan balik:

Jawa
// Not applicable for Java
Node.js
ref.off('value', originalCallback, ctx);

Jika Anda ingin menghapus semua panggilan balik di suatu lokasi, Anda dapat melakukan hal berikut:

Jawa
// No Java equivalent, listeners must be removed individually.
Node.js
// Remove all value callbacks
ref.off('value');

// Remove all callbacks of any type
ref.off();

Membaca Data Sekali

Dalam beberapa kasus mungkin berguna untuk panggilan balik untuk dipanggil sekali dan kemudian segera dihapus. Kami telah membuat fungsi pembantu untuk mempermudah ini:

Jawa
ref.addListenerForSingleValueEvent(new ValueEventListener() {
  @Override
  public void onDataChange(DataSnapshot dataSnapshot) {
    // ...
  }

  @Override
  public void onCancelled(DatabaseError databaseError) {
    // ...
  }
});
Node.js
ref.once('value', (data) => {
  // do some stuff once
});
Python
# Import database module.
from firebase_admin import db

# Get a database reference to our posts
ref = db.reference('server/saving-data/fireblog/posts')

# Read the data at the posts reference (this is a blocking operation)
print(ref.get())
Pergi
// Create a database client from App.
client, err := app.Database(ctx)
if err != nil {
	log.Fatalln("Error initializing database client:", err)
}

// Get a database reference to our posts
ref := client.NewRef("server/saving-data/fireblog/posts")

// Read the data at the posts reference (this is a blocking operation)
var post Post
if err := ref.Get(ctx, &post); err != nil {
	log.Fatalln("Error reading value:", err)
}

Meminta Data

Dengan kueri database Firebase, Anda dapat mengambil data secara selektif berdasarkan berbagai faktor. Untuk membuat kueri dalam database, Anda mulai dengan menentukan cara pengurutan data menggunakan salah satu fungsi pengurutan: orderByChild() , orderByKey() , atau orderByValue() . Anda kemudian dapat menggabungkan ini dengan lima metode lain untuk melakukan kueri kompleks: limitToFirst() , limitToLast() , startAt() , endAt() , dan equalTo() .

Karena kami semua di Firebase menganggap dinosaurus cukup keren, kami akan menggunakan cuplikan dari database sampel fakta dinosaurus untuk menunjukkan bagaimana Anda dapat mengkueri data di database Firebase Anda.:

{
  "lambeosaurus": {
    "height" : 2.1,
    "length" : 12.5,
    "weight": 5000
  },
  "stegosaurus": {
    "height" : 4,
    "length" : 9,
    "weight" : 2500
  }
}

Anda dapat mengurutkan data dengan tiga cara: menurut kunci anak , menurut kunci , atau menurut nilai . Kueri basis data dasar dimulai dengan salah satu fungsi pengurutan ini, yang masing-masing dijelaskan di bawah ini.

Memesan dengan kunci anak tertentu

Anda dapat mengurutkan node dengan kunci anak umum dengan meneruskan kunci tersebut ke orderByChild() . Misalnya, untuk membaca semua dinosaurus yang diurutkan berdasarkan ketinggian, Anda dapat melakukan hal berikut:

Jawa
public static class Dinosaur {

  public int height;
  public int weight;

  public Dinosaur(int height, int weight) {
    // ...
  }

}

final DatabaseReference dinosaursRef = database.getReference("dinosaurs");
dinosaursRef.orderByChild("height").addChildEventListener(new ChildEventListener() {
  @Override
  public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {
    Dinosaur dinosaur = dataSnapshot.getValue(Dinosaur.class);
    System.out.println(dataSnapshot.getKey() + " was " + dinosaur.height + " meters tall.");
  }

  // ...
});
Node.js
const ref = db.ref('dinosaurs');

ref.orderByChild('height').on('child_added', (snapshot) => {
  console.log(snapshot.key + ' was ' + snapshot.val().height + ' meters tall');
});
Python
ref = db.reference('dinosaurs')
snapshot = ref.order_by_child('height').get()
for key, val in snapshot.items():
    print('{0} was {1} meters tall'.format(key, val))
Pergi

// Dinosaur is a json-serializable type.
type Dinosaur struct {
	Height int `json:"height"`
	Width  int `json:"width"`
}

ref := client.NewRef("dinosaurs")

results, err := ref.OrderByChild("height").GetOrdered(ctx)
if err != nil {
	log.Fatalln("Error querying database:", err)
}
for _, r := range results {
	var d Dinosaur
	if err := r.Unmarshal(&d); err != nil {
		log.Fatalln("Error unmarshaling result:", err)
	}
	fmt.Printf("%s was %d meteres tall", r.Key(), d.Height)
}

Setiap simpul yang tidak memiliki kunci anak yang kita tanyakan diurutkan dengan nilai null , yang berarti ia akan didahulukan dalam pengurutan. Untuk detail tentang bagaimana data diurutkan, lihat bagian Bagaimana Data Diurutkan .

Kueri juga dapat dipesan oleh anak-anak yang sangat bersarang, bukan hanya anak-anak satu tingkat ke bawah. Ini berguna jika Anda memiliki data yang sangat bersarang seperti ini:

{
  "lambeosaurus": {
    "dimensions": {
      "height" : 2.1,
      "length" : 12.5,
      "weight": 5000
    }
  },
  "stegosaurus": {
    "dimensions": {
      "height" : 4,
      "length" : 9,
      "weight" : 2500
    }
  }
}

Untuk menanyakan ketinggian sekarang, Anda dapat menggunakan jalur lengkap ke objek daripada satu kunci:

Jawa
dinosaursRef.orderByChild("dimensions/height").addChildEventListener(new ChildEventListener() {
  @Override
  public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {
    // ...
  }

  // ...
});
Node.js
const ref = db.ref('dinosaurs');
ref.orderByChild('dimensions/height').on('child_added', (snapshot) => {
  console.log(snapshot.key + ' was ' + snapshot.val().height + ' meters tall');
});
Python
ref = db.reference('dinosaurs')
snapshot = ref.order_by_child('dimensions/height').get()
for key, val in snapshot.items():
    print('{0} was {1} meters tall'.format(key, val))
Pergi
ref := client.NewRef("dinosaurs")

results, err := ref.OrderByChild("dimensions/height").GetOrdered(ctx)
if err != nil {
	log.Fatalln("Error querying database:", err)
}
for _, r := range results {
	var d Dinosaur
	if err := r.Unmarshal(&d); err != nil {
		log.Fatalln("Error unmarshaling result:", err)
	}
	fmt.Printf("%s was %d meteres tall", r.Key(), d.Height)
}

Kueri hanya dapat dipesan dengan satu kunci pada satu waktu. Memanggil orderByChild() beberapa kali pada kueri yang sama menimbulkan kesalahan.

Memesan dengan kunci

Anda juga dapat mengurutkan node berdasarkan kuncinya menggunakan metode orderByKey() . Contoh berikut membaca semua dinosaurus dalam urutan abjad:

Jawa
dinosaursRef.orderByKey().addChildEventListener(new ChildEventListener() {
  @Override
  public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {
    System.out.println(dataSnapshot.getKey());
  }

  // ...
});
Node.js
var ref = db.ref('dinosaurs');
ref.orderByKey().on('child_added', (snapshot) => {
  console.log(snapshot.key);
});
Python
ref = db.reference('dinosaurs')
snapshot = ref.order_by_key().get()
print(snapshot)
Pergi
ref := client.NewRef("dinosaurs")

results, err := ref.OrderByKey().GetOrdered(ctx)
if err != nil {
	log.Fatalln("Error querying database:", err)
}
snapshot := make([]Dinosaur, len(results))
for i, r := range results {
	var d Dinosaur
	if err := r.Unmarshal(&d); err != nil {
		log.Fatalln("Error unmarshaling result:", err)
	}
	snapshot[i] = d
}
fmt.Println(snapshot)

Memesan berdasarkan nilai

Anda dapat mengurutkan node berdasarkan nilai kunci turunannya menggunakan metode orderByValue() . Katakanlah dinosaurus mengadakan kompetisi olahraga dino dan Anda mencatat skor mereka dalam format berikut:

{
  "scores": {
    "bruhathkayosaurus" : 55,
    "lambeosaurus" : 21,
    "linhenykus" : 80,
    "pterodactyl" : 93,
    "stegosaurus" : 5,
    "triceratops" : 22
  }
}

Untuk mengurutkan dinosaurus berdasarkan skornya, Anda dapat membuat kueri berikut:

Jawa
DatabaseReference scoresRef = database.getReference("scores");
scoresRef.orderByValue().addChildEventListener(new ChildEventListener() {
  @Override
  public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {
    System.out.println("The " + dataSnapshot.getKey() + " score is " + dataSnapshot.getValue());
  }

  // ...
});
Node.js
const scoresRef = db.ref('scores');
scoresRef.orderByValue().on('value', (snapshot) => {
  snapshot.forEach((data) => {
    console.log('The ' + data.key + ' dinosaur\'s score is ' + data.val());
  });
});
Python
ref = db.reference('scores')
snapshot = ref.order_by_value().get()
for key, val in snapshot.items():
    print('The {0} dinosaur\'s score is {1}'.format(key, val))
Pergi
ref := client.NewRef("scores")

results, err := ref.OrderByValue().GetOrdered(ctx)
if err != nil {
	log.Fatalln("Error querying database:", err)
}
for _, r := range results {
	var score int
	if err := r.Unmarshal(&score); err != nil {
		log.Fatalln("Error unmarshaling result:", err)
	}
	fmt.Printf("The %s dinosaur's score is %d\n", r.Key(), score)
}

Lihat bagian Bagaimana Data Diurutkan untuk penjelasan tentang bagaimana nilai null , boolean, string, dan objek diurutkan saat menggunakan orderByValue() .

Pertanyaan Kompleks

Sekarang setelah jelas bagaimana data Anda diurutkan, Anda dapat menggunakan metode batas atau rentang yang dijelaskan di bawah ini untuk membuat kueri yang lebih kompleks.

Batasi Kueri

limitToFirst() dan limitToLast() digunakan untuk menyetel jumlah maksimum turunan yang akan disinkronkan untuk panggilan balik tertentu. Jika Anda menetapkan batas 100, awalnya Anda hanya akan menerima hingga 100 peristiwa yang child_added . Jika Anda memiliki kurang dari 100 pesan yang disimpan dalam database Anda, event child_added akan diaktifkan untuk setiap pesan. Namun, jika Anda memiliki lebih dari 100 pesan, Anda hanya akan menerima event child_added untuk 100 pesan tersebut. Ini adalah 100 pesan terurut pertama jika Anda menggunakan limitToFirst() atau 100 pesan terurut terakhir jika Anda menggunakan limitToLast() . Saat item berubah, Anda akan menerima event child_added untuk item yang masuk ke kueri dan event child_removed untuk item yang keluar, sehingga jumlah totalnya tetap 100.

Menggunakan database fakta dinosaurus dan orderByChild() , Anda dapat menemukan dua dinosaurus terberat:

Jawa
dinosaursRef.orderByChild("weight").limitToLast(2).addChildEventListener(new ChildEventListener() {
  @Override
  public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {
    System.out.println(dataSnapshot.getKey());
  }

  // ...
});
Node.js
const ref = db.ref('dinosaurs');
ref.orderByChild('weight').limitToLast(2).on('child_added', (snapshot) => {
  console.log(snapshot.key);
});
Python
ref = db.reference('dinosaurs')
snapshot = ref.order_by_child('weight').limit_to_last(2).get()
for key in snapshot:
    print(key)
Pergi
ref := client.NewRef("dinosaurs")

results, err := ref.OrderByChild("weight").LimitToLast(2).GetOrdered(ctx)
if err != nil {
	log.Fatalln("Error querying database:", err)
}
for _, r := range results {
	fmt.Println(r.Key())
}

Callback child_added dipicu tepat dua kali, kecuali ada kurang dari dua dinosaurus yang disimpan dalam database. Itu juga akan dipecat untuk setiap dinosaurus baru yang lebih berat yang ditambahkan ke database. Dengan Python, kueri secara langsung mengembalikan OrderedDict yang berisi dua dinosaurus terberat.

Demikian pula, Anda dapat menemukan dua dinosaurus terpendek dengan menggunakan limitToFirst() :

Jawa
dinosaursRef.orderByChild("weight").limitToFirst(2).addChildEventListener(new ChildEventListener() {
  @Override
  public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {
    System.out.println(dataSnapshot.getKey());
  }

  // ...
});
Node.js
const ref = db.ref('dinosaurs');
ref.orderByChild('height').limitToFirst(2).on('child_added', (snapshot) => {
  console.log(snapshot.key);
});
Python
ref = db.reference('dinosaurs')
snapshot = ref.order_by_child('height').limit_to_first(2).get()
for key in snapshot:
    print(key)
Pergi
ref := client.NewRef("dinosaurs")

results, err := ref.OrderByChild("height").LimitToFirst(2).GetOrdered(ctx)
if err != nil {
	log.Fatalln("Error querying database:", err)
}
for _, r := range results {
	fmt.Println(r.Key())
}

Callback child_added dipicu tepat dua kali, kecuali ada kurang dari dua dinosaurus yang disimpan dalam database. Itu juga akan dipecat lagi jika salah satu dari dua dinosaurus pertama dihapus dari database, karena dinosaurus baru sekarang akan menjadi yang terpendek kedua. Dengan Python, kueri secara langsung mengembalikan OrderedDict yang berisi dinosaurus terpendek.

Anda juga dapat melakukan kueri batas dengan orderByValue() . Jika Anda ingin membuat papan peringkat dengan 3 dinosaurus olahraga dino dengan skor tertinggi, Anda dapat melakukan hal berikut:

Jawa
scoresRef.orderByValue().limitToFirst(3).addChildEventListener(new ChildEventListener() {
  @Override
  public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {
    System.out.println("The " + dataSnapshot.getKey() + " score is " + dataSnapshot.getValue());
  }

  // ...
});
Node.js
const scoresRef = db.ref('scores');
scoresRef.orderByValue().limitToLast(3).on('value', (snapshot)  =>{
  snapshot.forEach((data) => {
    console.log('The ' + data.key + ' dinosaur\'s score is ' + data.val());
  });
});
Python
scores_ref = db.reference('scores')
snapshot = scores_ref.order_by_value().limit_to_last(3).get()
for key, val in snapshot.items():
    print('The {0} dinosaur\'s score is {1}'.format(key, val))
Pergi
ref := client.NewRef("scores")

results, err := ref.OrderByValue().LimitToLast(3).GetOrdered(ctx)
if err != nil {
	log.Fatalln("Error querying database:", err)
}
for _, r := range results {
	var score int
	if err := r.Unmarshal(&score); err != nil {
		log.Fatalln("Error unmarshaling result:", err)
	}
	fmt.Printf("The %s dinosaur's score is %d\n", r.Key(), score)
}

Pertanyaan Rentang

Menggunakan startAt() , endAt() , dan equalTo() memungkinkan Anda memilih titik awal dan akhir yang sewenang-wenang untuk kueri Anda. Misalnya, jika Anda ingin menemukan semua dinosaurus yang tingginya minimal tiga meter, Anda dapat menggabungkan orderByChild() dan startAt() :

Jawa
dinosaursRef.orderByChild("height").startAt(3).addChildEventListener(new ChildEventListener() {
  @Override
  public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {
    System.out.println(dataSnapshot.getKey());
  }

  // ...
});
Node.js
const ref = db.ref('dinosaurs');
ref.orderByChild('height').startAt(3).on('child_added', (snapshot) => {
  console.log(snapshot.key);
});
Python
ref = db.reference('dinosaurs')
snapshot = ref.order_by_child('height').start_at(3).get()
for key in snapshot:
    print(key)
Pergi
ref := client.NewRef("dinosaurs")

results, err := ref.OrderByChild("height").StartAt(3).GetOrdered(ctx)
if err != nil {
	log.Fatalln("Error querying database:", err)
}
for _, r := range results {
	fmt.Println(r.Key())
}

Anda dapat menggunakan endAt() untuk menemukan semua dinosaurus yang namanya muncul sebelum Pterodactyl secara leksikografis:

Jawa
dinosaursRef.orderByKey().endAt("pterodactyl").addChildEventListener(new ChildEventListener() {
  @Override
  public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {
    System.out.println(dataSnapshot.getKey());
  }

  // ...
});
Node.js
const ref = db.ref('dinosaurs');
ref.orderByKey().endAt('pterodactyl').on('child_added', (snapshot) => {
  console.log(snapshot.key);
});
Python
ref = db.reference('dinosaurs')
snapshot = ref.order_by_key().end_at('pterodactyl').get()
for key in snapshot:
    print(key)
Pergi
ref := client.NewRef("dinosaurs")

results, err := ref.OrderByKey().EndAt("pterodactyl").GetOrdered(ctx)
if err != nil {
	log.Fatalln("Error querying database:", err)
}
for _, r := range results {
	fmt.Println(r.Key())
}

Anda dapat menggabungkan startAt() dan endAt() untuk membatasi kedua ujung kueri Anda. Contoh berikut menemukan semua dinosaurus yang namanya dimulai dengan huruf "b":

Jawa
dinosaursRef.orderByKey().startAt("b").endAt("b\uf8ff").addChildEventListener(new ChildEventListener() {
  @Override
  public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {
    System.out.println(dataSnapshot.getKey());
  }

  // ...
});
Node.js
var ref = db.ref('dinosaurs');
ref.orderByKey().startAt('b').endAt('b\uf8ff').on('child_added', (snapshot) => {
  console.log(snapshot.key);
});
Python
ref = db.reference('dinosaurs')
snapshot = ref.order_by_key().start_at('b').end_at(u'b\uf8ff').get()
for key in snapshot:
    print(key)
Pergi
ref := client.NewRef("dinosaurs")

results, err := ref.OrderByKey().StartAt("b").EndAt("b\uf8ff").GetOrdered(ctx)
if err != nil {
	log.Fatalln("Error querying database:", err)
}
for _, r := range results {
	fmt.Println(r.Key())
}

Metode equalTo() memungkinkan Anda memfilter berdasarkan kecocokan persis. Seperti halnya dengan kueri rentang lainnya, itu akan diaktifkan untuk setiap simpul anak yang cocok. Misalnya, Anda dapat menggunakan kueri berikut untuk menemukan semua dinosaurus yang tingginya 25 meter:

Jawa
dinosaursRef.orderByChild("height").equalTo(25).addChildEventListener(new ChildEventListener() {
  @Override
  public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {
    System.out.println(dataSnapshot.getKey());
  }

  // ...
});
Node.js
const ref = db.ref('dinosaurs');
ref.orderByChild('height').equalTo(25).on('child_added', (snapshot) => {
  console.log(snapshot.key);
});
Python
ref = db.reference('dinosaurs')
snapshot = ref.order_by_child('height').equal_to(25).get()
for key in snapshot:
    print(key)
Pergi
ref := client.NewRef("dinosaurs")

results, err := ref.OrderByChild("height").EqualTo(25).GetOrdered(ctx)
if err != nil {
	log.Fatalln("Error querying database:", err)
}
for _, r := range results {
	fmt.Println(r.Key())
}

Kueri rentang juga berguna saat Anda perlu membuat paginasi data Anda.

Menyatukan semuanya

Anda dapat menggabungkan semua teknik ini untuk membuat kueri yang kompleks. Misalnya, Anda dapat menemukan nama dinosaurus yang lebih pendek dari Stegosaurus:

Jawa
dinosaursRef.child("stegosaurus").child("height").addValueEventListener(new ValueEventListener() {
  @Override
  public void onDataChange(DataSnapshot stegoHeightSnapshot) {
    Integer favoriteDinoHeight = stegoHeightSnapshot.getValue(Integer.class);
    Query query = dinosaursRef.orderByChild("height").endAt(favoriteDinoHeight).limitToLast(2);
    query.addValueEventListener(new ValueEventListener() {
      @Override
      public void onDataChange(DataSnapshot dataSnapshot) {
        // Data is ordered by increasing height, so we want the first entry
        DataSnapshot firstChild = dataSnapshot.getChildren().iterator().next();
        System.out.println("The dinosaur just shorter than the stegosaurus is: " + firstChild.getKey());
      }

      @Override
      public void onCancelled(DatabaseError databaseError) {
        // ...
      }
    });
  }

  @Override
  public void onCancelled(DatabaseError databaseError) {
    // ...
  }
});
Node.js
  const ref = db.ref('dinosaurs');
  ref.child('stegosaurus').child('height').on('value', (stegosaurusHeightSnapshot) => {
    const favoriteDinoHeight = stegosaurusHeightSnapshot.val();

    const queryRef = ref.orderByChild('height').endAt(favoriteDinoHeight).limitToLast(2);
    queryRef.on('value', (querySnapshot) => {
      if (querySnapshot.numChildren() === 2) {
        // Data is ordered by increasing height, so we want the first entry
        querySnapshot.forEach((dinoSnapshot) => {
          console.log('The dinosaur just shorter than the stegasaurus is ' + dinoSnapshot.key);

          // Returning true means that we will only loop through the forEach() one time
          return true;
        });
      } else {
        console.log('The stegosaurus is the shortest dino');
      }
    });
});
Python
ref = db.reference('dinosaurs')
favotire_dino_height = ref.child('stegosaurus').child('height').get()
query = ref.order_by_child('height').end_at(favotire_dino_height).limit_to_last(2)
snapshot = query.get()
if len(snapshot) == 2:
    # Data is ordered by increasing height, so we want the first entry.
    # Second entry is stegosarus.
    for key in snapshot:
        print('The dinosaur just shorter than the stegosaurus is {0}'.format(key))
        return
else:
    print('The stegosaurus is the shortest dino')
Pergi
ref := client.NewRef("dinosaurs")

var favDinoHeight int
if err := ref.Child("stegosaurus").Child("height").Get(ctx, &favDinoHeight); err != nil {
	log.Fatalln("Error querying database:", err)
}

query := ref.OrderByChild("height").EndAt(favDinoHeight).LimitToLast(2)
results, err := query.GetOrdered(ctx)
if err != nil {
	log.Fatalln("Error querying database:", err)
}
if len(results) == 2 {
	// Data is ordered by increasing height, so we want the first entry.
	// Second entry is stegosarus.
	fmt.Printf("The dinosaur just shorter than the stegosaurus is %s\n", results[0].Key())
} else {
	fmt.Println("The stegosaurus is the shortest dino")
}

Bagaimana Data Diurutkan

Bagian ini menjelaskan bagaimana data Anda diurutkan saat menggunakan masing-masing dari empat fungsi pengurutan.

pesanOlehAnak

Saat menggunakan orderByChild() , data yang berisi kunci anak yang ditentukan akan diurutkan sebagai berikut:

  1. Anak-anak dengan nilai null untuk kunci anak yang ditentukan didahulukan.
  2. Anak-anak dengan nilai false untuk kunci anak yang ditentukan datang berikutnya. Jika beberapa anak memiliki nilai false , mereka diurutkan secara leksikografis berdasarkan kunci.
  3. Anak-anak dengan nilai true untuk kunci anak yang ditentukan datang berikutnya. Jika beberapa anak memiliki nilai true , mereka diurutkan secara leksikografis berdasarkan kunci.
  4. Anak-anak dengan nilai numerik datang berikutnya, diurutkan dalam urutan menaik. Jika beberapa anak memiliki nilai numerik yang sama untuk simpul anak yang ditentukan, mereka diurutkan berdasarkan kunci.
  5. String datang setelah angka, dan diurutkan secara leksikografis dalam urutan menaik. Jika beberapa anak memiliki nilai yang sama untuk simpul anak yang ditentukan, mereka diurutkan secara leksikografis berdasarkan kunci.
  6. Objek datang terakhir, dan diurutkan secara leksikografis berdasarkan kunci dalam urutan menaik.

orderByKey

Saat menggunakan orderByKey() untuk mengurutkan data Anda, data dikembalikan dalam urutan menaik menurut kunci sebagai berikut. Perlu diingat bahwa kunci hanya dapat berupa string.

  1. Anak-anak dengan kunci yang dapat diuraikan sebagai bilangan bulat 32-bit didahulukan, diurutkan dalam urutan menaik.
  2. Anak-anak dengan nilai string sebagai kunci mereka datang berikutnya, diurutkan secara leksikografis dalam urutan menaik.

pesanDenganNilai

Saat menggunakan orderByValue() , anak-anak diurutkan berdasarkan nilainya. Kriteria pengurutan sama seperti di orderByChild() , kecuali nilai simpul yang digunakan sebagai ganti nilai kunci anak yang ditentukan.