Mengambil Data dengan Firebase Realtime Database untuk C++

Dokumen ini mencakup dasar-dasar pengambilan data serta cara mengurutkan dan memfilter data Firebase.

Sebelum memulai

Pastikan Anda telah menyiapkan aplikasi dan dapat mengakses database, seperti yang dijelaskan dalam panduan Get Started.

Mengambil Data

Data Firebase diambil dengan panggilan satu kali ke GetValue() atau disertakan ke ValueListener pada referensi FirebaseDatabase. Pemroses nilai akan dipanggil satu kali untuk mengetahui status awal data, dan dipanggil lagi setiap kali data berubah.

Mendapatkan DatabaseReference

Untuk menulis data ke Database, Anda perlu instance DatabaseReference:

    // Get the root reference location of the database.
    firebase::database::DatabaseReference dbref = database->GetReference();

Membaca data sekali

Anda dapat menggunakan metode GetValue() untuk membaca snapshot statis konten di jalur tertentu sekali. Hasil tugas akan berisi snapshot yang berisi semua data di lokasi tersebut, termasuk data turunan. Jika tidak ada data, snapshot yang ditampilkan adalah null.

  firebase::Future<firebase::database::DataSnapshot> result =
    dbRef.GetReference("Leaders").GetValue();

Pada saat itu, permintaan telah dibuat, tetapi harus menunggu Future selesai untuk dapat membaca nilai. Karena game biasanya dijalankan dalam loop, dan tidak terlalu dikendalikan oleh callback dibanding aplikasi lain, Anda biasanya akan menanyakan penyelesaian.

  // In the game loop that polls for the result...

  if (result.status() != firebase::kFutureStatusPending) {
    if (result.status() != firebase::kFutureStatusComplete) {
      LogMessage("ERROR: GetValue() returned an invalid result.");
      // Handle the error...
    } else if (result.error() != firebase::database::kErrorNone) {
      LogMessage("ERROR: GetValue() returned error %d: %s", result.error(),
                 result.error_message());
      // Handle the error...
    } else {
      firebase::database::DataSnapshot snapshot = result.result();
      // Do something with the snapshot...
    }
  }

Hal ini menunjukkan beberapa pemeriksaan error dasar, lihat referensi firebase::Future untuk mengetahui informasi lebih lanjut tentang pemeriksaan error, serta cara menentukan kapan hasilnya siap.

Mendeteksi peristiwa

Anda dapat menambahkan pemroses untuk berlangganan perubahan data:

Class dasar ValueListener

Callback Penggunaan standar
OnValueChanged Membaca dan memproses perubahan di seluruh konten jalur.

Class dasar OnChildListener

OnChildAdded Mengambil daftar item atau memproses penambahan daftar item. Disarankan untuk digunakan dengan OnChildChanged dan OnChildRemoved untuk memantau perubahan daftar.
OnChildChanged Memproses perubahan pada item dalam daftar. Gunakan dengan OnChildAdded dan OnChildRemoved untuk memantau perubahan daftar.
OnChildRemoved Memproses item yang dihapus dari daftar. Gunakan dengan OnChildAdded dan OnChildChanged untuk memantau perubahan daftar.
OnChildMoved Mendeteksi perubahan urutan item dalam daftar terurut. Callback OnChildMoved selalu mengikuti callback OnChildChangedkarena adanya perubahan urutan item (berdasarkan metode 'urutkan menurut' saat ini).

Class ValueListener

Anda dapat menggunakan callback OnValueChanged untuk berlangganan perubahan konten di jalur tertentu. Callback ini terpicu satu kali ketika pemroses terpasang dan terpicu lagi setiap kali terjadi perubahan data, termasuk turunannya. Callback mendapatkan snapshot yang berisi semua data di lokasi tersebut, termasuk data turunan. Jika tidak ada data, snapshot yang ditampilkan adalah null.

Contoh berikut menunjukkan game yang mengambil skor di papan peringkat dari database:

  class LeadersValueListener : public firebase::database::ValueListener {
   public:
    void OnValueChanged(
        const firebase::database::DataSnapshot& snapshot) override {
      // Do something with the data in snapshot...
    }
    void OnCancelled(const firebase::database::Error& error_code,
                     const char* error_message) override {
      LogMessage("ERROR: LeadersValueListener canceled: %d: %s", error_code,
                 error_message);
    }
  };

  // Elsewhere in the code...

  LeadersValueListener* listener = new LeadersValueListener();
  firebase::Future<firebase::database::DataSnapshot> result =
    dbRef.GetReference("Leaders").AddValueListener(listener);

Hasil Future&ltDataSnaphot&gt berisi data di lokasi yang ditentukan dalam database pada saat peristiwa terjadi. Pemanggilan value() pada snapshot akan menampilkan Variant yang mewakili data tersebut.

Dalam contoh ini, metode OnCancelled juga diganti untuk mengetahui apakah pembacaan dibatalkan. Misalnya, proses baca bisa dibatalkan jika klien tidak memiliki izin untuk membaca dari lokasi database Firebase. database::Error akan menunjukkan mengapa kegagalan terjadi.

Class ChildListener

Peristiwa turunan dipicu sebagai respons terhadap operasi tertentu yang terjadi pada turunan node dari suatu operasi, seperti turunan baru yang ditambahkan melalui metode PushChild() atau turunan yang diperbarui melalui metode UpdateChildren(). Secara bersama-sama, setiap metode ini dapat berguna untuk memproses perubahan pada node tertentu dalam database. Misalnya, suatu game mungkin menggunakan metode ini secara bersamaan untuk memantau aktivitas dalam komentar sesi game, seperti yang ditunjukkan di bawah ini:

  class SessionCommentsChildListener : public firebase::database::ChildListener {
   public:
    void OnChildAdded(const firebase::database::DataSnapshot& snapshot,
                      const char* previous_sibling) override {
      // Do something with the data in snapshot ...
    }
    void OnChildChanged(const firebase::database::DataSnapshot& snapshot,
                        const char* previous_sibling) override {
      // Do something with the data in snapshot ...
    }
    void OnChildRemoved(
        const firebase::database::DataSnapshot& snapshot) override {
      // Do something with the data in snapshot ...
    }
    void OnChildMoved(const firebase::database::DataSnapshot& snapshot,
                      const char* previous_sibling) override {
      // Do something with the data in snapshot ...
    }
    void OnCancelled(const firebase::database::Error& error_code,
                     const char* error_message) override {
      LogMessage("ERROR: SessionCommentsChildListener canceled: %d: %s",
                 error_code, error_message);
    }
  };

  // elsewhere ....

  SessionCommentsChildListener* listener = new SessionCommentsChildListener();
  firebase::Future<firebase::database::DataSnapshot> result =
    dbRef.GetReference("GameSessionComments").AddChildListener(listener);

Callback OnChildAdded biasanya digunakan untuk mengambil daftar item di database Firebase. Callback OnChildAdded dipicu satu kali untuk setiap turunan yang ada, dan dipicu lagi setiap kali ada turunan baru yang ditambahkan ke lokasi yang ditetapkan. Pemroses meneruskan snapshot yang berisi data turunan baru.

Callback OnChildChanged dipanggil setiap kali node turunan diubah. Ini juga termasuk perubahan keturunan dari node turunan. Peristiwa ini biasanya digunakan bersamaan dengan panggilan OnChildAdded dan OnChildRemoved untuk menanggapi perubahan daftar item. Snapshot yang diteruskan ke pemroses berisi data turunan yang telah diperbarui.

Callback OnChildRemoved dipicu ketika turunan langsung dihapus. Peristiwa ini biasanya digunakan bersamaan dengan callback OnChildAdded dan OnChildChanged. Snapshot yang diteruskan ke callback berisi data turunan yang dihapus.

Callback OnChildMoved dipicu setiap kali panggilan OnChildChanged dimunculkan oleh update yang menyebabkan pengurutan ulang turunan. Peristiwa ini digunakan dengan data yang diurutkan dengan OrderByChild atau OrderByValue.

Mengurutkan dan memfilter data

Anda bisa menggunakan class Query Realtime Database untuk memperoleh data yang diurutkan berdasarkan kunci, nilai, atau nilai turunan. Anda juga dapat memfilter hasil pengurutan berdasarkan jumlah hasil tertentu atau berdasarkan rentang kunci atau nilai.

Mengurutkan data

Untuk mengambil data yang diurutkan, mulai dengan menentukan salah satu metode 'urutkan menurut' guna menentukan cara pengurutan hasil:

Metode Penggunaan
OrderByChild() Mengurutkan hasil menurut nilai kunci turunan tertentu.
OrderByKey() Mengurutkan hasil menurut kunci turunan.
OrderByValue() Mengurutkan hasil menurut nilai turunan.

Anda hanya bisa menggunakan satu metode 'urutkan menurut' pada satu waktu. Memanggil metode 'urutkan menurut' beberapa kali dalam satu kueri akan menghasilkan error.

Contoh berikut menunjukkan cara berlangganan papan peringkat skor yang diurutkan menurut skor.

  firebase::database::Query query =
    dbRef.GetReference("Leaders").OrderByChild("score");

  // To get the resulting DataSnapshot either use query.GetValue() and poll the
  // future, or use query.AddValueListener() and register to handle the
  // OnValueChanged callback.

Fungsi ini menentukan firebase::Query yang akan menyinkronkan klien dengan papan peringkat dalam database jika dikombinasikan dengan ValueListener, dan diurutkan menurut skor setiap entri. Anda dapat membaca informasi selengkapnya tentang penyusunan struktur data secara efisien di bagian Membuat Struktur Database.

Panggilan ke metode OrderByChild() menentukan kunci turunan yang dipakai sebagai dasar pengurutan hasil. Dalam kasus ini, hasil diurutkan menurut nilai "score" dalam setiap turunan. Untuk informasi lebih lanjut mengenai metode pengurutan jenis data lainnya, lihat Metode pengurutan data kueri.

Memfilter data

Untuk memfilter data, Anda dapat menggabungkan salah satu metode batas atau rentang dengan metode 'urutkan menurut' ketika menyusun kueri.

Metode Penggunaan
LimitToFirst() Menetapkan jumlah item maksimum untuk ditampilkan dari awal daftar hasil yang diurutkan.
LimitToLast() Menetapkan jumlah item maksimum untuk ditampilkan dari akhir daftar hasil yang diurutkan.
StartAt() Menampilkan item yang lebih besar atau sama dengan kunci atau nilai yang ditentukan, tergantung metode 'urutkan menurut' yang dipilih.
EndAt() Menampilkan item yang lebih kecil atau sama dengan kunci atau nilai yang ditentukan, tergantung metode 'urutkan menurut' yang dipilih.
EqualTo() Menampilkan item yang sama dengan kunci atau nilai yang ditentukan, tergantung metode 'urutkan menurut' yang dipilih.

Berbeda dengan metode 'urutkan menurut', Anda dapat menggabungkan beberapa fungsi batas atau rentang. Misalnya, Anda dapat menggabungkan metode StartAt() dan EndAt() untuk membatasi hasil ke rentang nilai tertentu.

Meskipun kueri hanya mendapatkan satu item yang cocok, snapshot-nya tetap berupa sebuah daftar, meski hanya memuat satu item.

Membatasi jumlah hasil

Anda dapat menggunakan metode LimitToFirst() dan LimitToLast() untuk menetapkan jumlah turunan maksimum yang akan disinkronkan untuk callback tertentu. Misalnya, jika Anda menggunakan LimitToFirst() untuk menetapkan batas 100, pada awalnya Anda hanya akan menerima hingga 100 callback OnChildAdded. Jika Anda memiliki kurang dari 100 item yang disimpan dalam database Firebase, callback OnChildAdded akan diaktifkan untuk setiap item.

Saat item berubah, Anda akan menerima callback OnChildAdded untuk item yang masuk ke kueri dan callback OnChildRemoved untuk item yang keluar dari kueri, sehingga jumlah totalnya tetap 100.

Misalnya, kode berikut menampilkan skor teratas dari papan peringkat:

  firebase::database::Query query =
    dbRef.GetReference("Leaders").OrderByChild("score").LimitToLast(1);

  // To get the resulting DataSnapshot either use query.GetValue() and poll the
  // future, or use query.AddValueListener() and register to handle the
  // OnValueChanged callback.

Filter berdasarkan kunci atau nilai

Anda dapat menggunakan StartAt(), EndAt(), dan EqualTo() untuk memilih titik awal, akhir, dan ekuivalensi yang arbitrer untuk kueri. Hal ini dapat bermanfaat untuk penomoran halaman data atau menemukan item dengan turunan yang memiliki nilai tertentu.

Cara data kueri diurutkan

Bagian ini menjelaskan cara pengurutan data menggunakan setiap metode 'urutkan menurut' di class Query.

OrderByChild

Jika Anda menggunakan OrderByChild(), data yang berisi kunci turunan yang ditentukan akan diurutkan sebagai berikut:

  1. Turunan yang memiliki nilai null untuk kunci turunan yang ditentukan akan muncul terlebih dahulu.
  2. Turunan yang memiliki nilai false untuk kunci turunan yang ditentukan akan muncul berikutnya. Jika beberapa turunan memiliki nilai false, turunan tersebut akan diurutkan secara leksikografis menurut kunci.
  3. Turunan yang memiliki nilai true untuk kunci turunan yang ditentukan akan muncul berikutnya. Jika beberapa turunan memiliki nilai true, turunan tersebut akan diurutkan secara leksikografis menurut kunci.
  4. Turunan dengan nilai numerik akan muncul berikutnya, dan diurutkan menaik. Jika beberapa turunan memiliki nilai numerik yang sama untuk node turunan yang ditentukan, turunan tersebut akan diurutkan menurut kunci.
  5. String muncul setelah angka, dan diurutkan secara leksikografis menaik. Jika beberapa turunan memiliki nilai yang sama untuk node turunan yang ditentukan, turunan tersebut akan diurutkan secara leksikografis menurut kunci.
  6. Objek akan muncul terakhir, dan diurutkan secara leksikografis menaik menurut kunci.

OrderByKey

Data yang diurutkan menggunakan OrderByKey() akan ditampilkan dalam urutan menaik menurut kunci.

  1. Turunan dengan kunci yang bisa diurai sebagai bilangan bulat 32-bit akan muncul terlebih dahulu, dan diurutkan menaik.
  2. Turunan dengan nilai string sebagai kuncinya akan muncul berikutnya, dan diurutkan secara leksikografis menaik.

OrderByValue

Jika menggunakan OrderByValue(), turunan akan diurutkan menurut nilainya. Kriteria urutan sama seperti di OrderByChild(), tetapi yang digunakan adalah nilai node, bukan nilai kunci turunan yang ditentukan.

Langkah Berikutnya