Advertisement
  1. Code
  2. Firebase

Memulai dengan Cloud Firestore untuk iOS

Scroll to top
Read Time: 13 min

() translation by (you can also view the original English article)

Programmer seluler telah mengambil keuntungan dari Backend Google seluler sebagai sebuah layanan fitur platform (MBaaS) Database Firebase yang realtime Selama bertahun - tahun, membantu merkea fokus dalam membangun fitur bagi aplikasi mereka tanpa perlu khawatir terhadap infrastruktur backend dan database. Dengan menjadikannya mudah menyimpan dan menyimpan data di Cloud serta memperhatikan autentikasi dan kemanan, Firebase memungkinkan programmer untuk fokus pada sisi klien.

Tahun lalu, Google mengumumkan solusi database backend lainnya, Cloud Firestore, dibangun dari bawah ke atas dengan komitmen pada skalanilitas dan intuitif yang lebih baik. Bagaimanapun juga, hal ini menimbullkan kebingunan tentang penempatannya dan hubugannya dengan produk unggulan yang sudah ada pada Google.Database realtime firebase. Tutoril ini akan menerangkan perbedaan antara dua platform dan keuntungan yang berbeda - beda dari masing - masing platform. Anda akan mempelajari bagaimana cara bekerja dengan refernsi dokumen firebase, seperti membaca, menulis, memperbarui dan menghapus data dalam realtime, dengan membangun sbuah aplikasi reminder sederhana.

Tujuan dari Tutorial ini

Tutorial ini akan memaparkan pada Anda tentang Cloud Firestore. Anda akan mempelajari cara memanfaatkan platform agar persistensi dan sinkronisasi databse menjadi real-time. Kami akan membahas topik - topik berikut ini :

  • Apa yang dimaksud dengan Cloud Firestore?
  • Data Model Firestore
  • Melakukan pengaturan pada Cloud Firestore
  • Membuat dan bekerja dengan referensi Cloud Firestore
  • Membaca data di waktu real-time dari Cloud Firestore
  • Membuat, Update dan menghapus data
  • Menyaring dan menggabungkan queries

Pengetahuan yang Diasumsikan

Tutorial ini menganggap anda telah memliki beberapa gambaran tentang Firebase dan latar belakang pengembangan dengan Swift dan Xcode.

Apa yang dimaksud dengan Cloud Firestore?

Seperti Database Firebase yang Realtime, Firestore memerikan pengembang web dan mobile sebuah solusi Cloud cross-platform untuk menyimpan data secara real-time, tanpa terbebani latency atau jaringan internet, serta integerasi tanpa batas dengan produk Google Cloud platform. Bersama dengan persamaan ini, terdapat keunggulan dan kelemahan yang berbeda yang membedakan satu dengan yang lainnya.

Data Model

Pada tingkatan dasar, Database Realtime menyimpan data sebagai suatu JSON tree yang besar, monolithic dan berhirarki (bertingkat - tingkat), sedangkan Firestore mengatur data dalam documents dan collections, seperti sub-collections. Hal ini membutuhkan sedikit denormalisasi Menyimpan data dalam satu JSON tree memiliki keuntungan berupa kemudahan saat bekerja dengan data requirements sederhana; namun itu menjadi lebih rumit pada skala dimana berurusan dengan hirarki data yang lebih kompleks.

Dukungan secara Offline

Kedua produk memberikan offline support, mengaktifkan cache data dalam antrian saat terjadi latent atau tidak ada koneksi jaringan - menyinkronkan perubahan lokal kembali ke backend bila memungkinkan. Firestore menunjang sinkronisasi offline.

Query dan Transaksi

Database realtime hanya menunjang pengurutan terbatas dan penyaringan kapabilitas - anda hanya dapat menyortir atau menyaring pada sebuah level property, tapi tidak keduanya, dalam sebuah single query. Query juga cukup dalam, artinya mereka mengembalikan sebagian besar hasil sub-tree kembali. Produknya hanya menunjang penulisan sederhana dan operasi transaksi yang membutuhkan sebuah callback penyelasaian

Firestore, di sisi lain, memperkenalkan query index dengan gabungan sorting(pengurutan) dan filtering(penyaringan), memungkinkan anda untuk mengkombinasikan aksi untuk membuat chain filters dan sorting. Anda juga dapat mengeksekusi query yang dangkal yang mengembalikan sub-collections sebagai pengganti seluruh collections yang akan anda dapatkan dengan Database realtime. Transaksi merupakan atom dalam alam, anda mau mengirim sekumpulan ataupun sebuah operasi tunggal, dengan mengulang transaksi secara otomatis sampai ditutup. Tambahan, database realtime hanya menunjang penulisan transaksi individu, sedangkan Firestore memberi sekumpulan operasi secara atom.

Kinerja dan Skalabilitas

Realtime Database, seperti yang Anda harapkan, cukup kuat dan memiliki latensi rendah. Namun, basis data dibatasi untuk wilayah tunggal, tergantung ketersediaan zona. Firestore, di samping itu, mewadahi data secara horizontal di beberapa zona dan wilayah untuk memastikan ketersediaan global yang sebenarnya, skalabilitas dan keandalan. Faktanya, Google telah menjanjikan bila Firestore akan menjadi lebih handal dibanding Database realtime.

Kekurangan lain dari database realtime adalah keterbatasan hingga 100,000 user yang berbarengan (100,000 koneksi yang berlangsung secra bersamaan dan 1000 tulisan/detik dalam sebuah database tunggal) dalam rangka untuk memnunjang lebih banyak user. Firesotre secara otomatis menskalakan beberapa contoh tanpa campur tangan anda.

Dirancang dari bawah ke atas dengan pertimbangan skalabilitas, Firestore memiliki sebuah arsitektur yang mereplikasi data di wilayah multiple data, memerhatikan autentikasi, dan menangani hal - hal yang berkaitan dengan keamanan lainnya di dalam SDK dari sisi kliennya. Data model baru lebih intuitif dibanding milik Firebase, lebih menyerupai solusi database NoSQL lain yang sebanding seperti MongoDB, sambil menyediakan mesin query yang lebih kuat.

Keamanan

Pada akhirnya, database realtime, seperti yang anda ketahui dari tutorial sebelumnya mengatur keamanan melalui aturan cascading dengan trigger validasi terpisah. Hal ini bekerja dengan aturan Database firebase, memvalidasi data secara terpisah. Firestore, di sisi lain, menyediakan model keamanan yang lebih sederhana namun lebih kuat yang memanfaatkan aturan keamanan Cloud Firestore serta Identitas dan manajemen akses (IAM), dengan validasi data yang dikecualikan secara otomatis.

Firestore Data Model

Firestore adalah sebuah database NoSQL berbasis dokumen, terdiri dari kumpulan dokumen, yang masing - masing terdiri dari data. Sama seperti sbuah database NoSQL, anda tidak akan memperoleh tables, rows, dan elemen lainnya yang akan anda dapatkan dalam sebuah database yang berhubungan, bukannya kumpulan pasangan key / value yang akan anda temukan di dalam dokumen.

Anda membuat dokumen dan sekumpulan implisit dengan mengirimkan data ke sebuah dokumen, dan jika dokumen atau koleksinya tidak ada, hal itu secara otomatis akan dibuat untuk anda, sama dengan koleksi harus selalu menjadi akar (simpul) pertama. Berikut ini adalah contoh skema Tugas sederhana dari proyek yang akan Anda kerjakan segera, yang terdiri dari koleksi Tugas, seperti jumlah dokumen yang terdiri dari dua bidang. namanya (string), dan sebuah tanda apakah tugas sudah selesai atau belum (boolean).

simple Tasks example schema of the project simple Tasks example schema of the project simple Tasks example schema of the project

Mari kita uraikan setiap elemen agar anda dapayt memahaminya dengan lebih baik.

Collection

Serupa dengan tabel database di dunia SQL, collections terdiri dari satu atau lebih dokumen. Collection harus menjadi elemen akar utama dalam skema anda dan hanya dapat terdiri dari dokumen, bukan collection lainnya. Namun, anda dapat merujuk ke dokumen yang gilirannya merujuk ke collections (sub-collection).

Diagram of document and collectionsDiagram of document and collectionsDiagram of document and collections

Pada diagram diatas, sebuah tugas(task) terdiri dari dua bidang primitif (name dan done) sama seperti sebuah sub-collection yang terdiri dari dua bidang primitifnya sendiri.

Dokumen

Dokumen terdiri dari pasangan key / value, dengan value memiliki salah satu tipe dari berikut ini :

  • primitive fields (misalnya string, angka, boolean)
  • Objek kompleks bertingkat (daftar array primitif)
  • sub-collection

Nested object juga disebut maps dan dapat direpreentasikan sebagai berikut, di dalam dokumen. Berikut ini adalah sebuah contoh dari nested object dan array, masing - masing:

1
ID: 2422892 //primitive
2
name: “Remember to buy milk” 
3
detail: //nested object
4
    notes: "This is a task to buy milk from the store"
5
  created: 2017-04-09
6
	due: 2017-04-10
7
done: false
8
notify: ["2F22-89R2", "L092-G623", "H00V-T4S1"]
9
...

Untuk informasi lebih lanjut tentang tipe data yang didukung, lihat Google Tipe - tipe Data Dokumentasi. Selanjutnya, anda akan menyiapkan sebuah projek untuk bekerja dengan Cloud Firestore.

Menyiapkan Proyek

Jika anda telah bekerja dengan Firebase sebelumnya, kebanyakan dari ini pasti familiar dengan anda. Jika tidak, anda memerlukan sebuah akun di Firebase dan mengikuti instruksi dalam bagian "Menyiapkan Proyek" pada tutorial sebelumnya,Mulai dengan Autentikasi Firebase untuk iOS.

Untuk mengikuti rangkaian tutorial ini tutorial project repo. Next, include the Firestore library by adding the following to your Podfile:

1
pod 'Firebase/Core' 
2
pod 'Firebase/Firestore'

Masukkan yang berikut di terminal Anda untuk membangun library anda:

1
pod install

Selanjutnya, beralih ke Xcode dan buka file .xcworkspace.Arahkan ke file AppDelegate.swift dan masukkan yang berikut dalam method aplikasi application:didFinishLaunchingWithOptions:

1
FirebaseApp.configure()

Di browser Anda, buka Firebase console dan pilih tabDatabasedi sebelah kiri.

Database tab in the Firebase consoleDatabase tab in the Firebase consoleDatabase tab in the Firebase console

Pastikan Anda memilih opsi untuk Mulai dalam Mode Testsehingga Anda tidak memiliki masalah keamanan apa pun saat kami bereksperimen, dan memperhatikan pemberitahuan keamanan saat Anda memindahkan aplikasi ke dalam produksi. Anda sekarang siap untuk membuat koleksi dan beberapa contoh dokumen.

Menambahkan Collection dan Dokumen Contoh

Untuk memulai, buat koleksi awal Tasks, dengan memilih tombol Tambahkan Koleksi dan memberi nama koleksi, seperti yang digambarkan di bawah ini:

naming the collectionnaming the collectionnaming the collection

Untuk dokumen pertama, Anda akan membiarkan ID Dokumen kosong, yang akan secara otomatis menghasilkan ID untuk Anda. Dokumen hanya akan terdiri dari dua bidang: namedan done.

Document with two fieldsDocument with two fieldsDocument with two fields

Simpan dokumen, dan Anda harus dapat mengonfirmasi pengumpulan dan dokumen bersama dengan ID yang dihasilkan secara otomatis:

collection and document with the auto-generated IDcollection and document with the auto-generated IDcollection and document with the auto-generated ID

Dengan mengatur database dengan dokumen sampel di cloud, Anda siap untuk mulai menerapkan SDK Firestore di Xcode.

Menciptakan & bekerja dengan referensi Database

Buka file MasterViewController.swift di Xcode dan tambahkan baris berikut untuk mengimpor library:

1
import Firebase
2
3
class MasterViewController: UITableViewController {
4
    @IBOutlet weak var addButton: UIBarButtonItem!
5
    
6
    private var documents: [DocumentSnapshot] = []
7
    public var tasks: [Task] = []
8
    private var listener : ListenerRegistration!
9
   ...

Di sini Anda hanya membuat variabel listener yang akan memungkinkan Anda untuk memicu sebuah koneksi ke database secara real time ketika ada perubahan. Anda juga membuat referensi DocumentSnapshotyang akan menyimpan snapshot data sementara.

Sebelum melanjutkan dengan pengontrol tampilan, buat file swift lain, Task.swift, yang akan mewakili model data Anda:

1
import Foundation
2
3
struct Task{
4
    var name:String
5
    var done: Bool
6
    var id: String
7
    
8
    var dictionary: [String: Any] {
9
        return [
10
            "name": name,
11
            "done": done
12
        ]
13
    }
14
}
15
16
extension Task{
17
    init?(dictionary: [String : Any], id: String) {
18
        guard   let name = dictionary["name"] as? String,
19
            let done = dictionary["done"] as? Bool
20
            else { return nil }
21
        
22
        self.init(name: name, done: done, id: id)
23
    }
24
}

Potongan kode di atas termasuk properti kenyamanan (kamus) dan metode (init) yang akan membuat pengisian objek model lebih mudah. Beralih kembali ke pengontrol tampilan, dan deklarasikan variabel pengatur global yang akan membatasi query basis ke 50 entri teratas dalam daftar tugas. Anda juga akan menghapus pendengar setelah Anda mengatur variabel query, sebagaimana dilambangkan dalam properti didSet di bawah ini:

1
fileprivate func baseQuery() -> Query {
2
        return Firestore.firestore().collection("Tasks").limit(to: 50)
3
    }
4
    
5
    fileprivate var query: Query? {
6
        didSet {
7
            if let listener = listener {
8
                listener.remove()
9
            }
10
        }
11
    }
12
13
override func viewDidLoad() {
14
        super.viewDidLoad()
15
        self.query = baseQuery()
16
    }
17
18
 override func viewWillDisappear(_ animated: Bool) {
19
        super.viewWillDisappear(animated)
20
        self.listener.remove()
21
    }

Membaca Data Secara Real Time Dari Cloud Firestore

Dengan referensi dokumen di tempat, viewWillAppear(_animated: Bool), kaitkan pendengar yang Anda buat sebelumnya dengan hasil snapshot query, dan ambil daftar dokumen. Ini dilakukan dengan memanggil metode query?.addSnapshotListener di Firestore:

1
self.listener =  query?.addSnapshotListener { (documents, error) in
2
            guard let snapshot = documents else {
3
                print("Error fetching documents results: \(error!)")
4
                return
5
            }
6
            
7
            let results = snapshot.documents.map { (document) -> Task in
8
                if let task = Task(dictionary: document.data(), id: document.documentID) {
9
                    return task
10
                } else {
11
                    fatalError("Unable to initialize type \(Task.self) with dictionary \(document.data())")
12
                }
13
            }
14
            
15
            self.tasks = results
16
            self.documents = snapshot.documents
17
            self.tableView.reloadData()
18
            
19
        }

Penutupan di atas menetapkan snapshot.documents dengan memetakan array secara iteratif dan membungkusnya ke objek contoh Model tugas baru Task untuk setiap item data dalam snapshot. Jadi hanya dengan beberapa baris, Anda telah berhasil membaca di semua tasks dari cloud dan menugaskan mereka ke array tasksglobal.

Untuk menampilkan hasil, isi metode delegasi TableViewberikut:

1
override func numberOfSections(in tableView: UITableView) -> Int {
2
        return 1
3
    }
4
    
5
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
6
        return tasks.count
7
    }
8
    
9
    
10
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
11
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
12
        
13
        let item = tasks[indexPath.row]
14
        
15
        cell.textLabel!.text = item.name
16
        cell.textLabel!.textColor = item.done == false ? UIColor.black : UIColor.lightGray
17
        
18
        return cell
19
    }

Pada tahap ini, buat dan jalankan proyek dan di simulator anda harus dapat mengamati data yang muncul secara real time. Tambahkan data melalui console Firebase dan Anda akan melihatnya muncul secara instan di simulator aplikasi.

Data appearing in the app simulatorData appearing in the app simulatorData appearing in the app simulator

Membuat, Memperbarui dan Menghapus Data

Setelah berhasil membaca konten dari back-end, selanjutnya Anda akan membuat, memperbarui dan menghapus data. Contoh berikut akan mengilustrasikan cara memperbarui data, menggunakan contoh yang dibuat di mana aplikasi hanya akan membiarkan Anda menandai item seperti yang dilakukan dengan mengetuk cell. Perhatikan collection.document(item.id).updateData(["done": !item.done]) properti penutup, yang hanya mereferensikan ID dokumen tertentu, memperbarui masing-masing bidang di dalam kamus:

1
override func tableView(_ tableView: UITableView,
2
                            didSelectRowAt indexPath: IndexPath) {
3
4
        let item = tasks[indexPath.row]
5
        let collection = Firestore.firestore().collection("Tasks")
6
7
        collection.document(item.id).updateData([
8
            "done": !item.done,
9
            ]) { err in
10
                if let err = err {
11
                    print("Error updating document: \(err)")
12
                } else {
13
                    print("Document successfully updated")
14
                }
15
        }
16
17
        tableView.reloadRows(at: [indexPath], with: .automatic)
18
        
19
    }

Untuk menghapus item, panggil metode document(item.id).delete():

1
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
2
        return true
3
    }
4
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
5
6
        if (editingStyle == .delete){
7
            let item = tasks[indexPath.row]
8
            _ = Firestore.firestore().collection("Tasks").document(item.id).delete()
9
        }
10
11
    }

Membuat task baru akan melibatkan penambahan tombol baru di Storyboard Anda dan menghubungkan IBAction ke view controller, membuat sebuah methode addTask(_ sender:). Ketika pengguna menekan tombol, itu akan memunculkan lembar peringatan di mana pengguna dapat menambahkan nama task baru:

1
collection("Tasks").addDocument
2
    (data: ["name": textFieldReminder.text ?? 
3
        "empty task", "done": false])
4

Lengkapi bagian akhir aplikasi dengan memasukkan:

1
@IBAction func addTask(_ sender: Any) {
2
        
3
        let alertVC : UIAlertController = UIAlertController(title: "New Task", message: "What do you want to remember?", preferredStyle: .alert)
4
        
5
        alertVC.addTextField { (UITextField) in
6
            
7
        }
8
        
9
        let cancelAction = UIAlertAction.init(title: "Cancel", style: .destructive, handler: nil)
10
        
11
        alertVC.addAction(cancelAction)
12
        
13
        //Alert action closure
14
        let addAction = UIAlertAction.init(title: "Add", style: .default) { (UIAlertAction) -> Void in
15
            
16
            let textFieldReminder = (alertVC.textFields?.first)! as UITextField
17
            
18
            let db = Firestore.firestore()
19
            var docRef: DocumentReference? = nil
20
            docRef = db.collection("Tasks").addDocument(data: [
21
                "name": textFieldReminder.text ?? "empty task",
22
                "done": false
23
            ]) { err in
24
                if let err = err {
25
                    print("Error adding document: \(err)")
26
                } else {
27
                    print("Document added with ID: \(docRef!.documentID)")
28
                }
29
            }
30
            
31
        }
32
    
33
        alertVC.addAction(addAction)
34
        present(alertVC, animated: true, completion: nil)
35
        
36
    }

Bangun dan jalankan aplikasi sekali lagi dan, ketika simulator muncul, coba tambahkan dalam beberapa tasks, serta menandai beberapa sebagai done (selesai), dan akhirnya menguji fungsi hapus dengan menghapus beberapa task. Anda dapat mengonfirmasi bahwa data yang disimpan telah diperbarui secara waktu nyata dengan beralih ke console database Firebase dan mengamati koleksi dan dokumen.

collection and documents in the consolecollection and documents in the consolecollection and documents in the console

Memfilter dan Menyusun Query

Sejauh ini, Anda hanya bekerja dengan query sederhana, tanpa kemampuan pemfilteran tertentu. Untuk membuat query yang sedikit lebih canggih, Anda dapat memfilter berdasarkan nilai tertentu dengan menggunakan whereField clause:

1
docRef.whereField(“name”, isEqualTo: searchString)

You can order and limit your query data, by making use of the order(by: ) and limit(to: ) methods as follows:

1
docRef.order(by: "name").limit(5)

Di aplikasi FirebaseDo, Anda sudah memanfaatkan penggunaan batas berbasis query. Dalam cuplikan di atas, Anda juga memanfaatkan fitur lain, mencampur query, di mana urutan dan batas keduanya dirangkai bersama. Anda dapat menautkan sebanyak mungkin query yang Anda inginkan, seperti dalam contoh berikut:

1
docRef
2
    .whereField(“name”, isEqualTo: searchString)
3
	.whereField(“done”, isEqualTo: false)
4
	.order(by: "name")
5
	.limit(5)

Kesimpulan

Dalam tutorial ini, Anda menjelajahi produk MBaaS Google yang baru, Cloud Firestore, dan dalam prosesnya membuat aplikasi pengingat task sederhana yang menunjukkan betapa mudahnya Anda mempertahankan, menyinkronkan, dan menanyakan data Anda di Cloud. Anda telah belajar tentang struktur skema data Firestore dibandingkan dengan Database Firebase secara Realtime dan cara membaca dan menulis data secara real time, serta memperbarui dan menghapus data. Anda juga belajar cara membuat query sederhana serta query gabungan, dan cara memfilter data.

Cloud Firestoredibuat dengan tujuan untuk menyediakan ketahanan Database Firebase secara Realtime tanpa banyak keterbatasan yang harus ditanggung oleh pengembang seluler, terutama karena berkaitan dengan skalabilitas dan melakukan query. Kami hanya menggores permukaan apa yang dapat Anda capai dengan Firestore, dan tentu saja perlu ditelusuri beberapa konsep yang lebih maju, seperti Paginating Data dengan Query CursorsMengelola Indexes, dan Mengamankan data anda.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.