Buka konsol

Menangani Daftar Data di iOS

Mendapatkan FIRDatabaseReference

Untuk membaca atau menulis data dari database, Anda memerlukan instance FIRDatabaseReference:

Swift

var ref: DatabaseReference!
ref = Database.database().reference()

Objective-C

@property (strong, nonatomic) FIRDatabaseReference *ref;
self.ref = [[FIRDatabase database] reference];

Membaca dan menulis daftar

Menambahkan ke daftar data

Gunakan metode childByAutoId untuk menambahkan data ke daftar dalam aplikasi multipengguna. Metode childByAutoId menghasilkan kunci unik setiap kali turunan baru ditambahkan ke referensi Firebase tertentu. Dengan menggunakan kunci yang dihasilkan secara otomatis untuk setiap elemen baru dalam daftar, beberapa klien dapat menambahkan turunan ke lokasi yang sama secara bersamaan tanpa ada konflik tulis. Kunci unik yang dihasilkan oleh childByAutoId didasarkan pada stempel waktu, sehingga item daftar otomatis diurutkan secara kronologis.

Anda dapat menggunakan referensi data baru yang ditampilkan oleh metode childByAutoId untuk mendapatkan nilai kunci turunan yang otomatis dihasilkan atau data kumpulan untuk turunan. Memanggil getKey pada referensi childByAutoId akan menampilkan kunci yang dihasilkan secara otomatis.

Anda dapat menggunakan kunci yang dihasilkan secara otomatis ini untuk mempermudah dalam meratakan struktur data. Untuk mengetahui informasi lebih lanjut, lihat contoh data fan-out.

Mendeteksi peristiwa turunan

Peristiwa turunan dipicu sebagai tanggapan terhadap operasi tertentu yang terjadi pada turunan node dari suatu operasi, seperti turunan baru yang ditambahkan melalui metode childByAutoId atau turunan yang sedang diupdate melalui metode updateChildValues.

Jenis peristiwa Penggunaan standar
FIRDataEventTypeChildAdded Mengambil daftar item atau mendeteksi penambahan daftar item. Peristiwa ini dipicu satu kali untuk setiap turunan yang ada, dan dipicu lagi setiap kali ada turunan baru yang ditambahkan ke lokasi yang ditetapkan. Snapshot yang berisi data turunan baru diteruskan ke listener.
FIRDataEventTypeChildChanged Mendeteksi perubahan pada item dalam daftar. Peristiwa ini dipicu setiap kali node turunan diubah. Ini juga termasuk perubahan keturunan dari node turunan. Snapshot yang diteruskan ke listener peristiwa berisi data turunan yang diupdate.
FIRDataEventTypeChildRemoved Mendeteksi item yang sedang dihapus dari daftar. Peristiwa ini dipicu ketika turunan langsung dihapus.Snapshot yang diteruskan ke pemblokiran callback berisi data turunan yang dihapus.
FIRDataEventTypeChildMoved Mendeteksi perubahan urutan item dalam daftar terurut. Peristiwa ini dipicu setiap kali update menyebabkan pengurutan ulang turunan. Peristiwa ini digunakan dengan data yang diurutkan berdasarkan queryOrderedByChild atau queryOrderedByValue.

Secara bersama-sama, setiap metode ini dapat berguna untuk mendeteksi perubahan terhadap node tertentu dalam database. Misalnya, aplikasi blogging sosial mungkin menggunakan metode ini secara bersama-sama untuk memantau aktivitas dalam komentar suatu postingan, seperti terlihat di bawah ini:

Swift

// Listen for new comments in the Firebase database
commentsRef.observe(.childAdded, with: { (snapshot) -> Void in
  self.comments.append(snapshot)
  self.tableView.insertRows(at: [IndexPath(row: self.comments.count-1, section: self.kSectionComments)], with: UITableView.RowAnimation.automatic)
})
// Listen for deleted comments in the Firebase database
commentsRef.observe(.childRemoved, with: { (snapshot) -> Void in
  let index = self.indexOfMessage(snapshot)
  self.comments.remove(at: index)
  self.tableView.deleteRows(at: [IndexPath(row: index, section: self.kSectionComments)], with: UITableView.RowAnimation.automatic)
})

Objective-C

// Listen for new comments in the Firebase database
[_commentsRef
              observeEventType:FIRDataEventTypeChildAdded
              withBlock:^(FIRDataSnapshot *snapshot) {
                [self.comments addObject:snapshot];
                [self.tableView insertRowsAtIndexPaths:@[
                  [NSIndexPath indexPathForRow:self.comments.count - 1 inSection:kSectionComments]
                ]
                                      withRowAnimation:UITableViewRowAnimationAutomatic];
              }];
// Listen for deleted comments in the Firebase database
[_commentsRef
 observeEventType:FIRDataEventTypeChildRemoved
 withBlock:^(FIRDataSnapshot *snapshot) {
   int index = [self indexOfMessage:snapshot];
   [self.comments removeObjectAtIndex:index];
   [self.tableView deleteRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:index inSection:kSectionComments]]
                         withRowAnimation:UITableViewRowAnimationAutomatic];
 }];

Mendeteksi peristiwa nilai

Meskipun mendeteksi peristiwa turunan adalah cara yang disarankan untuk membaca daftar data, mendeteksi peristiwa nilai di referensi daftar dalam beberapa situasi bisa menjadi hal yang bermanfaat.

Jika observer FIRDataEventTypeValue dipasang ke daftar data, daftar data akan ditampilkan secara keseluruhan sebagai DataSnapshot tunggal, yang nantinya dapat di-loop untuk mengakses masing-masing turunan.

Meskipun hanya ada satu kueri yang cocok, snapshot tetaplah sebuah daftar yang berisi satu item. Untuk mengakses item tersebut, Anda harus melakukan loop atas hasil:

Swift

_commentsRef.observe(.value) { snapshot in
  for child in snapshot.children {
    ...
  }
}

Objective-C

[_commentsRef
              observeEventType:FIRDataEventTypeValue
              withBlock:^(FIRDataSnapshot *snapshot) {
                // Loop over children
                NSEnumerator *children = [snapshot children];
                FIRDataSnapshot *child;
                while (child = [children nextObject]) {
                  // ...
                }
              }];

Pola ini dapat berguna ketika Anda ingin mengambil semua turunan dari daftar dalam sebuah operasi, dan bukannya mendeteksi peristiwa penambahan turunan lain.

Mengurutkan dan memfilter data

Anda dapat menggunakan kelas FIRDatabaseQuery pada Realtime Database untuk mengambil data yang diurutkan berdasarkan kunci, nilai, atau nilai turunan. Anda juga dapat memfilter hasil pengurutan ke jumlah hasil tertentu atau berbagai kunci atau nilai.

Mengurutkan data

Untuk mengambil data yang diurutkan, mulai dengan menentukan salah satu metode 'urutkan berdasarkan' untuk menentukan cara pengurutan hasil.

Metode Penggunaan
queryOrderedByKey Hasil urutan berdasarkan kunci turunan.
queryOrderedByValue Mengurutkan hasil berdasarkan nilai turunan.
queryOrderedByChild Mengurutkan hasil berdasarkan nilai kunci turunan yang ditentukan atau lokasi turunan bertingkat.

Anda hanya dapat menggunakan satu metode urutkan-berdasarkan pada satu waktu. Memanggil metode 'urutkan berdasarkan' beberapa kali dalam kueri yang sama akan menyebabkan error.

Contoh berikut menunjukkan cara mengambil daftar postingan teratas milik pengguna yang diurutkan berdasarkan jumlah bintangnya:

Swift

// My top posts by number of stars
let myTopPostsQuery = (ref.child("user-posts").child(getUid())).queryOrdered(byChild: "starCount")

Objective-C

// My top posts by number of stars
FIRDatabaseQuery *myTopPostsQuery = [[[self.ref child:@"user-posts"]
                                      child:[super getUid]]
                                     queryOrderedByChild:@"starCount"];

Kueri ini memperoleh postingan pengguna dari lokasi dalam database berdasarkan ID penggunanya yang diurutkan berdasarkan jumlah bintang yang diterima setiap postingan. Teknik penggunaan ID sebagai kunci indeks ini disebut data fan out. Anda dapat membaca lebih lanjut tentang hal ini di bagian Membuat Struktur Database Anda.

Panggilan ke metode queryOrderedByChild menentukan kunci turunan sebagai dasar pengurutan hasil. Dalam contoh ini, postingan diurutkan berdasarkan nilai turunan "starCount" di setiap postingan. Kueri juga dapat diurutkan berdasarkan turunan bertingkat, jika Anda memiliki data yang tampak seperti ini:

"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",
  }
},

Dalam kasus ini, kita dapat mengurutkan elemen daftar berdasarkan nilai yang bersarang dalam kunci metrics dengan menentukan lokasi relatif ke turunan bertingkat pada panggilan queryOrderedByChild.

Swift

 
let postsByMostPopular = ref.child("posts").queryOrdered(byChild: "metrics/views")

Objective-C

 
FIRDatabaseQuery *postsByMostPopular = [[ref child:@"posts"] queryOrderedByChild:@"metrics/views"];

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 berdasarkan' ketika menyusun kueri.

Metode Penggunaan
queryLimitedToFirst Menetapkan jumlah item maksimum untuk ditampilkan dari awal daftar hasil yang diurutkan.
queryLimitedToLast Menetapkan jumlah item maksimum untuk ditampilkan dari akhir daftar hasil yang diurutkan.
queryStartingAtValue Menampilkan item yang lebih besar atau sama dengan kunci atau nilai yang ditentukan, tergantung metode 'urutkan berdasarkan' yang dipilih.
queryEndingAtValue Menampilkan item yang lebih kecil atau sama dengan kunci atau nilai yang ditentukan, tergantung metode 'urutkan berdasarkan' yang dipilih.
queryEqualToValue Menampilkan item yang sama dengan kunci atau nilai yang ditentukan, tergantung metode 'urutkan berdasarkan' yang dipilih.

Berbeda dengan metode urutkan-berdasarkan, Anda dapat menggabungkan beberapa fungsi batas atau rentang. Misalnya, Anda dapat menggabungkan metode queryStartingAtValue dan queryEndingAtValue guna membatasi hasil ke rentang nilai tertentu.

Membatasi jumlah hasil

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

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

Kasus berikut menunjukkan bagaimana contoh aplikasi blogging dapat mengambil daftar 100 postingan terbaru oleh semua pengguna:

Swift

// Last 100 posts, these are automatically the 100 most recent
// due to sorting by push() keys
let recentPostsQuery = (ref?.child("posts").queryLimited(toFirst: 100))!

Objective-C

// Last 100 posts, these are automatically the 100 most recent
// due to sorting by push() keys
FIRDatabaseQuery *recentPostsQuery = [[self.ref child:@"posts"] queryLimitedToFirst:100];

Filter berdasarkan kunci atau nilai

Anda dapat menggunakan queryStartingAtValue, queryEndingAtValue, dan queryEqualToValue untuk memilih titik arbitrer mulai, akhir, atau yang setara untuk kueri. Hal ini dapat bermanfaat untuk pemberian nomor data atau menemukan item dengan turunan yang memiliki nilai tertentu.

Cara data kueri diurutkan

Bagian ini berisi penjelasan mengenai cara data diurutkan menggunakan setiap metode urutkan-berdasarkan di kelas FIRDatabaseQuery.

queryOrderedByKey

Jika Anda menggunakan queryOrderedByKey untuk mengurutkan data, data akan ditampilkan dalam urutan menaik berdasarkan kunci.

  1. Turunan dengan kunci yang dapat diurai sebagai bilangan bulat 32-bit berada di urutan pertama, diurutkan dalam urutan menaik.
  2. Turunan dengan nilai string sebagai kuncinya berada di urutan berikutnya, diurutkan secara leksikografis dalam urutan menaik.

queryOrderedByValue

Jika Anda menggunakan queryOrderedByValue, turunan akan diurutkan berdasarkan nilainya. Kriteria pengurutannya sama dengan queryOrderedByChild. Bedanya, nilai node digunakan sebagai ganti nilai kunci turunan yang ditentukan.

queryOrderedByChild

Jika Anda menggunakan queryOrderedByChild, data yang berisi kunci turunan yang ditentukan akan diurutkan sebagai berikut:

  1. Turunan yang memiliki nilai nil 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 berdasarkan 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 berdasarkan kunci.
  4. Turunan dengan nilai numerik akan muncul berikutnya, dan diurutkan dalam urutan menaik. Jika beberapa turunan memiliki nilai numerik yang sama untuk node turunan yang ditentukan, turunan tersebut akan diurutkan berdasarkan kunci.
  5. String muncul setelah angka, dan diurutkan secara leksikografis dalam urutan menaik. Jika beberapa turunan memiliki nilai yang sama untuk node turunan yang ditentukan, turunan tersebut akan diurutkan secara leksikografis berdasarkan kunci.
  6. Objek muncul terakhir, dan diurutkan secara leksikografis berdasarkan kunci dalam urutan menaik.

Melepas listener

Observer tidak secara otomatis menghentikan sinkronisasi data saat Anda meninggalkan ViewController. Jika tidak dihapus dengan benar, observer akan terus menyinkronkan data ke memori lokal. Jika observer tidak lagi diperlukan, hapuslah dengan meneruskan FIRDatabaseHandle yang terkait ke metode removeObserverWithHandle.

Saat pemblokiran callback ditambahkan ke referensi, FIRDatabaseHandle akan ditampilkan. Handle ini dapat digunakan untuk menghapus pemblokiran callback.

Jika beberapa listener ditambahkan ke referensi database, setiap listener akan dipanggil ketika terjadi peristiwa. Untuk menghentikan sinkronisasi data di lokasi tersebut, Anda harus menghapus semua observer di sebuah lokasi dengan memanggil metode removeAllObservers.

Memanggil removeObserverWithHandle atau removeAllObservers di listener tidak akan otomatis menghapus listener yang terdaftar pada node turunannya. Anda juga harus tetap melacak referensi atau handle tersebut untuk menghapusnya.

Langkah Berikutnya