1. Ikhtisar
Sasaran
Dalam codelab ini Anda akan membuat aplikasi rekomendasi restoran di Android yang didukung oleh Cloud Firestore. Anda akan belajar cara:
- Membaca dan menulis data ke Firestore dari aplikasi Android
- Dengarkan perubahan data Firestore secara realtime
- Gunakan Firebase Authentication dan aturan keamanan untuk mengamankan data Firestore
- Tulis kueri Firestore yang kompleks
Prasyarat
Sebelum memulai codelab ini, pastikan Anda memiliki:
- Android Studio Flamingo atau lebih baru
- Emulator Android dengan API 19 atau lebih tinggi
- Node.js versi 16 atau lebih tinggi
- Java versi 17 atau lebih tinggi
2. Buat proyek Firebase
- Masuk ke Firebase console dengan akun Google Anda.
- Di Firebase console , klik Tambahkan proyek .
- Seperti yang ditunjukkan pada tangkapan layar di bawah, masukkan nama untuk proyek Firebase Anda (misalnya, "Makanan Ramah"), dan klik Lanjutkan .
- Anda mungkin diminta untuk mengaktifkan Google Analytics, untuk tujuan codelab ini pilihan Anda tidak menjadi masalah.
- Setelah sekitar satu menit, proyek Firebase Anda akan siap. Klik Lanjutkan .
3. Siapkan proyek sampel
Unduh kodenya
Jalankan perintah berikut untuk mengkloning kode contoh untuk codelab ini. Ini akan membuat folder bernama friendlyeats-android
di mesin Anda:
$ git clone https://github.com/firebase/friendlyeats-android
Jika Anda tidak memiliki git di mesin Anda, Anda juga dapat mengunduh kodenya langsung dari GitHub.
Tambahkan konfigurasi Firebase
- Di Firebase console , pilih Ikhtisar Proyek di navigasi kiri. Klik tombol Android untuk memilih platform. Saat dimintai nama paket, gunakan
com.google.firebase.example.fireeats
- Klik Daftar Aplikasi dan ikuti petunjuk untuk mengunduh file
google-services.json
, dan memindahkannya ke folderapp/
kode yang baru saja Anda unduh. Kemudian klik Berikutnya .
Impor proyek
Buka Android Studio. Klik File > Baru > Impor Proyek dan pilih folder Friendlyeats-android .
4. Siapkan Emulator Firebase
Dalam codelab ini Anda akan menggunakan Firebase Emulator Suite untuk mengemulasikan Cloud Firestore dan layanan Firebase lainnya secara lokal. Hal ini memberikan lingkungan pengembangan lokal yang aman, cepat, dan tanpa biaya untuk membangun aplikasi Anda.
Instal Firebase CLI
Pertama, Anda perlu menginstal Firebase CLI . Jika Anda menggunakan macOS atau Linux, Anda dapat menjalankan perintah cURL berikut:
curl -sL https://firebase.tools | bash
Jika Anda menggunakan Windows, baca petunjuk instalasi untuk mendapatkan biner mandiri atau menginstal melalui npm
.
Setelah Anda menginstal CLI, menjalankan firebase --version
akan melaporkan versi 9.0.0
atau lebih tinggi:
$ firebase --version 9.0.0
Gabung
Jalankan firebase login
untuk menghubungkan CLI ke akun Google Anda. Ini akan membuka jendela browser baru untuk menyelesaikan proses login. Pastikan untuk memilih akun yang sama dengan yang Anda gunakan saat membuat proyek Firebase sebelumnya.
Tautkan proyek Anda
Dari dalam folder friendlyeats-android
jalankan firebase use --add
untuk menghubungkan proyek lokal Anda ke proyek Firebase Anda. Ikuti petunjuk untuk memilih proyek yang Anda buat sebelumnya dan jika diminta untuk memilih alias masukkan default
.
5. Jalankan aplikasinya
Sekarang saatnya menjalankan Firebase Emulator Suite dan aplikasi Android FriendlyEats untuk pertama kalinya.
Jalankan emulator
Di terminal Anda dari dalam direktori friendlyeats-android
jalankan firebase emulators:start
untuk memulai Firebase Emulator. Anda akan melihat log seperti ini:
$ firebase emulators:start i emulators: Starting emulators: auth, firestore i firestore: Firestore Emulator logging to firestore-debug.log i ui: Emulator UI logging to ui-debug.log ┌─────────────────────────────────────────────────────────────┐ │ ✔ All emulators ready! It is now safe to connect your app. │ │ i View Emulator UI at http://localhost:4000 │ └─────────────────────────────────────────────────────────────┘ ┌────────────────┬────────────────┬─────────────────────────────────┐ │ Emulator │ Host:Port │ View in Emulator UI │ ├────────────────┼────────────────┼─────────────────────────────────┤ │ Authentication │ localhost:9099 │ http://localhost:4000/auth │ ├────────────────┼────────────────┼─────────────────────────────────┤ │ Firestore │ localhost:8080 │ http://localhost:4000/firestore │ └────────────────┴────────────────┴─────────────────────────────────┘ Emulator Hub running at localhost:4400 Other reserved ports: 4500 Issues? Report them at https://github.com/firebase/firebase-tools/issues and attach the *-debug.log files.
Anda sekarang memiliki lingkungan pengembangan lokal lengkap yang berjalan di mesin Anda! Pastikan perintah ini tetap berjalan selama sisa codelab, aplikasi Android Anda harus terhubung ke emulator.
Hubungkan aplikasi ke Emulator
Buka file util/FirestoreInitializer.kt
dan util/AuthInitializer.kt
di Android Studio. File-file ini berisi logika untuk menghubungkan Firebase SDK ke emulator lokal yang berjalan di mesin Anda, saat aplikasi dimulai.
Pada metode create()
kelas FirestoreInitializer
, periksa potongan kode ini:
// Use emulators only in debug builds
if (BuildConfig.DEBUG) {
firestore.useEmulator(FIRESTORE_EMULATOR_HOST, FIRESTORE_EMULATOR_PORT)
}
Kami menggunakan BuildConfig
untuk memastikan kami hanya terhubung ke emulator saat aplikasi kami berjalan dalam mode debug
. Saat kami mengkompilasi aplikasi dalam mode release
, kondisi ini akan salah.
Kita dapat melihat bahwa ia menggunakan metode useEmulator(host, port)
untuk menghubungkan Firebase SDK ke emulator Firestore lokal. Di seluruh aplikasi, kami akan menggunakan FirebaseUtil.getFirestore()
untuk mengakses instance FirebaseFirestore
ini sehingga kami yakin bahwa kami selalu terhubung ke emulator Firestore saat dijalankan dalam mode debug
.
Jalankan aplikasi
Jika Anda telah menambahkan file google-services.json
dengan benar, proyek sekarang harus dikompilasi. Di Android Studio klik Build > Rebuild Project dan pastikan tidak ada error yang tersisa.
Di Android Studio Jalankan aplikasi di emulator Android Anda. Pada awalnya Anda akan disajikan dengan layar "Masuk". Anda dapat menggunakan email dan kata sandi apa pun untuk masuk ke aplikasi. Proses masuk ini terhubung ke emulator Firebase Authentication, sehingga tidak ada kredensial nyata yang dikirimkan.
Sekarang buka UI Emulator dengan menavigasi ke http://localhost:4000 di browser web Anda. Kemudian klik pada tab Otentikasi dan Anda akan melihat akun yang baru saja Anda buat:
Setelah Anda menyelesaikan proses masuk, Anda akan melihat layar beranda aplikasi:
Kami akan segera menambahkan beberapa data untuk mengisi layar beranda.
6. Tulis data ke Firestore
Di bagian ini kita akan menulis beberapa data ke Firestore sehingga kita dapat mengisi layar beranda yang saat ini kosong.
Objek model utama di aplikasi kita adalah restoran (lihat model/Restaurant.kt
). Data Firestore dibagi menjadi dokumen, koleksi, dan subkoleksi. Kami akan menyimpan setiap restoran sebagai dokumen dalam koleksi tingkat atas yang disebut "restaurants"
. Untuk mempelajari lebih lanjut model data Firestore, baca tentang dokumen dan koleksi di dokumentasi .
Untuk tujuan demonstrasi, kami akan menambahkan fungsionalitas dalam aplikasi untuk membuat sepuluh restoran acak ketika kami mengklik tombol "Tambahkan Item Acak" di menu tambahan. Buka file MainFragment.kt
dan ganti konten dalam metode onAddItemsClicked()
dengan:
private fun onAddItemsClicked() {
val restaurantsRef = firestore.collection("restaurants")
for (i in 0..9) {
// Create random restaurant / ratings
val randomRestaurant = RestaurantUtil.getRandom(requireContext())
// Add restaurant
restaurantsRef.add(randomRestaurant)
}
}
Ada beberapa hal penting yang perlu diperhatikan tentang kode di atas:
- Kami mulai dengan mendapatkan referensi ke koleksi
"restaurants"
. Koleksi dibuat secara implisit ketika dokumen ditambahkan, sehingga tidak perlu membuat koleksi sebelum menulis data. - Dokumen dapat dibuat menggunakan kelas data Kotlin, yang kami gunakan untuk membuat setiap dokumen Restoran.
- Metode
add()
menambahkan dokumen ke koleksi dengan ID yang dibuat secara otomatis, sehingga kita tidak perlu menentukan ID unik untuk setiap Restoran.
Sekarang jalankan kembali aplikasinya dan klik tombol "Tambahkan Item Acak" di menu tambahan (di pojok kanan atas) untuk menjalankan kode yang baru saja Anda tulis:
Sekarang buka UI Emulator dengan menavigasi ke http://localhost:4000 di browser web Anda. Kemudian klik pada tab Firestore dan Anda akan melihat data yang baru saja Anda tambahkan:
Data ini 100% lokal untuk mesin Anda. Faktanya, proyek Anda yang sebenarnya belum berisi database Firestore! Artinya aman untuk bereksperimen dengan mengubah dan menghapus data ini tanpa konsekuensi.
Selamat, Anda baru saja menulis data ke Firestore! Pada langkah selanjutnya kita akan mempelajari cara menampilkan data ini di aplikasi.
7. Menampilkan data dari Firestore
Pada langkah ini kita akan mempelajari cara mengambil data dari Firestore dan menampilkannya di aplikasi kita. Langkah pertama untuk membaca data dari Firestore adalah membuat Query
. Buka file MainFragment.kt
dan tambahkan kode berikut ke awal metode onViewCreated()
:
// Firestore
firestore = Firebase.firestore
// Get the 50 highest rated restaurants
query = firestore.collection("restaurants")
.orderBy("avgRating", Query.Direction.DESCENDING)
.limit(LIMIT.toLong())
Sekarang kami ingin mendengarkan kueri, sehingga kami mendapatkan semua dokumen yang cocok dan diberitahu tentang pembaruan di masa mendatang secara real time. Karena tujuan akhir kita adalah mengikat data ini ke RecyclerView
, kita perlu membuat kelas RecyclerView.Adapter
untuk memproses data.
Buka kelas FirestoreAdapter
, yang telah diimplementasikan sebagian. Pertama, mari kita buat adaptor mengimplementasikan EventListener
dan menentukan fungsi onEvent
sehingga dapat menerima pembaruan pada kueri Firestore:
abstract class FirestoreAdapter<VH : RecyclerView.ViewHolder>(private var query: Query?) :
RecyclerView.Adapter<VH>(),
EventListener<QuerySnapshot> { // Add this implements
// ...
// Add this method
override fun onEvent(documentSnapshots: QuerySnapshot?, e: FirebaseFirestoreException?) {
// Handle errors
if (e != null) {
Log.w(TAG, "onEvent:error", e)
return
}
// Dispatch the event
if (documentSnapshots != null) {
for (change in documentSnapshots.documentChanges) {
// snapshot of the changed document
when (change.type) {
DocumentChange.Type.ADDED -> {
// TODO: handle document added
}
DocumentChange.Type.MODIFIED -> {
// TODO: handle document changed
}
DocumentChange.Type.REMOVED -> {
// TODO: handle document removed
}
}
}
}
onDataChanged()
}
// ...
}
Pada pemuatan awal, pendengar akan menerima satu peristiwa ADDED
untuk setiap dokumen baru. Saat kumpulan hasil kueri berubah seiring waktu, pendengar akan menerima lebih banyak peristiwa yang berisi perubahan tersebut. Sekarang mari kita selesaikan penerapan pendengar. Pertama tambahkan tiga metode baru: onDocumentAdded
, onDocumentModified
, dan onDocumentRemoved
:
private fun onDocumentAdded(change: DocumentChange) {
snapshots.add(change.newIndex, change.document)
notifyItemInserted(change.newIndex)
}
private fun onDocumentModified(change: DocumentChange) {
if (change.oldIndex == change.newIndex) {
// Item changed but remained in same position
snapshots[change.oldIndex] = change.document
notifyItemChanged(change.oldIndex)
} else {
// Item changed and changed position
snapshots.removeAt(change.oldIndex)
snapshots.add(change.newIndex, change.document)
notifyItemMoved(change.oldIndex, change.newIndex)
}
}
private fun onDocumentRemoved(change: DocumentChange) {
snapshots.removeAt(change.oldIndex)
notifyItemRemoved(change.oldIndex)
}
Kemudian panggil metode baru ini dari onEvent
:
override fun onEvent(documentSnapshots: QuerySnapshot?, e: FirebaseFirestoreException?) {
// Handle errors
if (e != null) {
Log.w(TAG, "onEvent:error", e)
return
}
// Dispatch the event
if (documentSnapshots != null) {
for (change in documentSnapshots.documentChanges) {
// snapshot of the changed document
when (change.type) {
DocumentChange.Type.ADDED -> {
onDocumentAdded(change) // Add this line
}
DocumentChange.Type.MODIFIED -> {
onDocumentModified(change) // Add this line
}
DocumentChange.Type.REMOVED -> {
onDocumentRemoved(change) // Add this line
}
}
}
}
onDataChanged()
}
Terakhir implementasikan metode startListening()
untuk melampirkan pendengar:
fun startListening() {
if (registration == null) {
registration = query.addSnapshotListener(this)
}
}
Sekarang aplikasi telah dikonfigurasi sepenuhnya untuk membaca data dari Firestore. Jalankan kembali aplikasinya dan Anda akan melihat restoran yang Anda tambahkan pada langkah sebelumnya:
Sekarang kembali ke UI Emulator di browser Anda dan edit salah satu nama restoran. Anda akan melihatnya berubah di aplikasi hampir seketika!
8. Menyortir dan memfilter data
Aplikasi saat ini menampilkan restoran dengan peringkat teratas di seluruh koleksi, namun dalam aplikasi restoran sebenarnya, pengguna ingin mengurutkan dan memfilter data. Misalnya, aplikasi harus dapat menampilkan "Restoran makanan laut terbaik di Philadelphia" atau "Pizza paling murah".
Mengklik bilah putih di bagian atas aplikasi akan menampilkan dialog filter. Di bagian ini kita akan menggunakan kueri Firestore agar dialog ini berfungsi:
Mari kita edit metode onFilter()
pada MainFragment.kt
. Metode ini menerima objek Filters
yang merupakan objek pembantu yang kita buat untuk menangkap keluaran dialog filter. Kami akan mengubah metode ini untuk membuat kueri dari filter:
override fun onFilter(filters: Filters) {
// Construct query basic query
var query: Query = firestore.collection("restaurants")
// Category (equality filter)
if (filters.hasCategory()) {
query = query.whereEqualTo(Restaurant.FIELD_CATEGORY, filters.category)
}
// City (equality filter)
if (filters.hasCity()) {
query = query.whereEqualTo(Restaurant.FIELD_CITY, filters.city)
}
// Price (equality filter)
if (filters.hasPrice()) {
query = query.whereEqualTo(Restaurant.FIELD_PRICE, filters.price)
}
// Sort by (orderBy with direction)
if (filters.hasSortBy()) {
query = query.orderBy(filters.sortBy.toString(), filters.sortDirection)
}
// Limit items
query = query.limit(LIMIT.toLong())
// Update the query
adapter.setQuery(query)
// Set header
binding.textCurrentSearch.text = HtmlCompat.fromHtml(
filters.getSearchDescription(requireContext()),
HtmlCompat.FROM_HTML_MODE_LEGACY
)
binding.textCurrentSortBy.text = filters.getOrderDescription(requireContext())
// Save filters
viewModel.filters = filters
}
Dalam cuplikan di atas kita membuat objek Query
dengan melampirkan klausa where
dan orderBy
untuk mencocokkan filter yang diberikan.
Jalankan kembali aplikasi dan pilih filter berikut untuk menampilkan restoran harga rendah paling populer:
Anda sekarang akan melihat daftar restoran terfilter yang hanya berisi opsi harga rendah:
Jika Anda sudah sampai sejauh ini, kini Anda telah membuat aplikasi melihat rekomendasi restoran yang berfungsi penuh di Firestore! Anda sekarang dapat mengurutkan dan memfilter restoran secara real time. Di beberapa bagian berikutnya kami akan menambahkan ulasan ke restoran dan menambahkan aturan keamanan ke aplikasi.
9. Atur data dalam subkoleksi
Di bagian ini kami akan menambahkan peringkat ke aplikasi sehingga pengguna dapat mengulas restoran favorit mereka (atau yang paling tidak favorit).
Koleksi dan subkoleksi
Sejauh ini kami telah menyimpan semua data restoran di koleksi tingkat atas yang disebut "restoran". Saat pengguna menilai sebuah restoran, kami ingin menambahkan objek Rating
baru ke restoran tersebut. Untuk tugas ini kita akan menggunakan subkoleksi. Anda dapat menganggap subkoleksi sebagai koleksi yang dilampirkan pada dokumen. Jadi setiap dokumen restoran akan memiliki subkoleksi rating yang penuh dengan dokumen rating. Subkoleksi membantu mengatur data tanpa membuat dokumen kami membengkak atau memerlukan kueri yang rumit.
Untuk mengakses subkoleksi, panggil .collection()
pada dokumen induk:
val subRef = firestore.collection("restaurants")
.document("abc123")
.collection("ratings")
Anda dapat mengakses dan menanyakan subkoleksi seperti halnya koleksi tingkat atas, tidak ada batasan ukuran atau perubahan kinerja. Anda dapat membaca selengkapnya tentang model data Firestore di sini .
Menulis data dalam suatu transaksi
Menambahkan Rating
ke subkoleksi yang tepat hanya memerlukan pemanggilan .add()
, namun kita juga perlu memperbarui rating rata-rata objek Restaurant
dan jumlah rating untuk mencerminkan data baru. Jika kita menggunakan operasi terpisah untuk melakukan kedua perubahan ini, ada sejumlah kondisi balapan yang dapat mengakibatkan data basi atau salah.
Untuk memastikan bahwa peringkat ditambahkan dengan benar, kami akan menggunakan transaksi untuk menambahkan peringkat ke sebuah restoran. Transaksi ini akan melakukan beberapa tindakan:
- Baca peringkat restoran saat ini dan hitung peringkat baru
- Tambahkan peringkat ke subkoleksi
- Perbarui peringkat rata-rata restoran dan jumlah peringkat
Buka RestaurantDetailFragment.kt
dan implementasikan fungsi addRating
:
private fun addRating(restaurantRef: DocumentReference, rating: Rating): Task<Void> {
// Create reference for new rating, for use inside the transaction
val ratingRef = restaurantRef.collection("ratings").document()
// In a transaction, add the new rating and update the aggregate totals
return firestore.runTransaction { transaction ->
val restaurant = transaction.get(restaurantRef).toObject<Restaurant>()
?: throw Exception("Restaurant not found at ${restaurantRef.path}")
// Compute new number of ratings
val newNumRatings = restaurant.numRatings + 1
// Compute new average rating
val oldRatingTotal = restaurant.avgRating * restaurant.numRatings
val newAvgRating = (oldRatingTotal + rating.rating) / newNumRatings
// Set new restaurant info
restaurant.numRatings = newNumRatings
restaurant.avgRating = newAvgRating
// Commit to Firestore
transaction.set(restaurantRef, restaurant)
transaction.set(ratingRef, rating)
null
}
}
Fungsi addRating()
mengembalikan Task
yang mewakili keseluruhan transaksi. Dalam fungsi onRating()
pendengar ditambahkan ke tugas untuk merespons hasil transaksi.
Sekarang Jalankan aplikasinya lagi dan klik salah satu restoran, yang akan memunculkan layar detail restoran. Klik tombol + untuk mulai menambahkan ulasan. Tambahkan ulasan dengan memilih sejumlah bintang dan memasukkan beberapa teks.
Menekan Kirim akan memulai transaksi. Ketika transaksi selesai, Anda akan melihat ulasan Anda ditampilkan di bawah dan pembaruan jumlah ulasan restoran:
Selamat! Anda kini memiliki aplikasi ulasan restoran seluler lokal dan sosial yang dibangun di Cloud Firestore. Saya dengar itu sangat populer akhir-akhir ini.
10. Amankan data Anda
Sejauh ini kami belum mempertimbangkan keamanan aplikasi ini. Bagaimana kita tahu bahwa pengguna hanya dapat membaca dan menulis data sendiri yang benar? Basis data Firestore diamankan dengan file konfigurasi yang disebut Aturan Keamanan .
Buka file firestore.rules
, Anda akan melihat yang berikut:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
//
// WARNING: These rules are insecure! We will replace them with
// more secure rules later in the codelab
//
allow read, write: if request.auth != null;
}
}
}
Mari kita ubah aturan ini untuk mencegah akses atau perubahan data yang tidak diinginkan, buka file firestore.rules
dan ganti kontennya dengan yang berikut:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Determine if the value of the field "key" is the same
// before and after the request.
function isUnchanged(key) {
return (key in resource.data)
&& (key in request.resource.data)
&& (resource.data[key] == request.resource.data[key]);
}
// Restaurants
match /restaurants/{restaurantId} {
// Any signed-in user can read
allow read: if request.auth != null;
// Any signed-in user can create
// WARNING: this rule is for demo purposes only!
allow create: if request.auth != null;
// Updates are allowed if no fields are added and name is unchanged
allow update: if request.auth != null
&& (request.resource.data.keys() == resource.data.keys())
&& isUnchanged("name");
// Deletes are not allowed.
// Note: this is the default, there is no need to explicitly state this.
allow delete: if false;
// Ratings
match /ratings/{ratingId} {
// Any signed-in user can read
allow read: if request.auth != null;
// Any signed-in user can create if their uid matches the document
allow create: if request.auth != null
&& request.resource.data.userId == request.auth.uid;
// Deletes and updates are not allowed (default)
allow update, delete: if false;
}
}
}
}
Aturan ini membatasi akses untuk memastikan bahwa klien hanya melakukan perubahan yang aman. Misalnya pembaruan pada dokumen restoran hanya dapat mengubah peringkat, bukan nama atau data lainnya yang tidak dapat diubah. Peringkat hanya dapat dibuat jika ID pengguna cocok dengan pengguna yang login, sehingga mencegah spoofing.
Untuk membaca selengkapnya tentang Aturan Keamanan, kunjungi dokumentasi .
11. Kesimpulan
Anda sekarang telah membuat aplikasi berfitur lengkap di atas Firestore. Anda telah mempelajari tentang fitur-fitur Firestore yang paling penting, termasuk:
- Dokumen dan koleksi
- Membaca dan menulis data
- Menyortir dan memfilter dengan kueri
- Subkoleksi
- Transaksi
Belajarlah lagi
Untuk terus mempelajari Firestore, berikut beberapa tempat yang baik untuk memulai:
Aplikasi restoran dalam codelab ini didasarkan pada contoh aplikasi "Makanan Ramah". Anda dapat menelusuri kode sumber untuk aplikasi itu di sini .
Opsional: Penerapan ke produksi
Sejauh ini aplikasi ini hanya menggunakan Firebase Emulator Suite. Jika Anda ingin mempelajari cara men-deploy aplikasi ini ke proyek Firebase yang sebenarnya, lanjutkan ke langkah berikutnya.
12. (Opsional) Terapkan aplikasi Anda
Sejauh ini aplikasi ini sepenuhnya bersifat lokal, semua datanya terdapat di Firebase Emulator Suite. Di bagian ini Anda akan mempelajari cara mengonfigurasi proyek Firebase Anda agar aplikasi ini dapat berfungsi dalam produksi.
Otentikasi Firebase
Di Firebase console, buka bagian Autentikasi dan klik Mulai . Navigasikan ke tab Metode masuk dan pilih opsi Email/Kata Sandi dari Penyedia asli .
Aktifkan metode masuk Email/Kata Sandi dan klik Simpan .
toko pemadam kebakaran
Buat basis data
Navigasikan ke bagian Firestore Database di konsol dan klik Create Database :
- Saat ditanya tentang Aturan Keamanan pilih untuk memulai dalam Mode Produksi , kami akan segera memperbarui aturan tersebut.
- Pilih lokasi database yang ingin Anda gunakan untuk aplikasi Anda. Perhatikan bahwa memilih lokasi database adalah keputusan permanen dan untuk mengubahnya Anda harus membuat proyek baru. Untuk informasi lebih lanjut tentang memilih lokasi proyek, lihat dokumentasi .
Aturan Penerapan
Untuk menerapkan Aturan Keamanan yang Anda tulis sebelumnya, jalankan perintah berikut di direktori codelab:
$ firebase deploy --only firestore:rules
Ini akan menyebarkan konten firestore.rules
ke proyek Anda, yang dapat Anda konfirmasi dengan membuka tab Aturan di konsol.
Terapkan Indeks
Aplikasi FriendlyEats memiliki penyortiran dan pemfilteran rumit yang memerlukan sejumlah indeks gabungan khusus. Ini dapat dibuat secara manual di Firebase console, tetapi lebih mudah untuk menulis definisinya di file firestore.indexes.json
dan menerapkannya menggunakan Firebase CLI.
Jika Anda membuka file firestore.indexes.json
Anda akan melihat bahwa indeks yang diperlukan telah disediakan:
{
"indexes": [
{
"collectionId": "restaurants",
"queryScope": "COLLECTION",
"fields": [
{ "fieldPath": "city", "mode": "ASCENDING" },
{ "fieldPath": "avgRating", "mode": "DESCENDING" }
]
},
{
"collectionId": "restaurants",
"queryScope": "COLLECTION",
"fields": [
{ "fieldPath": "category", "mode": "ASCENDING" },
{ "fieldPath": "avgRating", "mode": "DESCENDING" }
]
},
{
"collectionId": "restaurants",
"queryScope": "COLLECTION",
"fields": [
{ "fieldPath": "price", "mode": "ASCENDING" },
{ "fieldPath": "avgRating", "mode": "DESCENDING" }
]
},
{
"collectionId": "restaurants",
"queryScope": "COLLECTION",
"fields": [
{ "fieldPath": "city", "mode": "ASCENDING" },
{ "fieldPath": "numRatings", "mode": "DESCENDING" }
]
},
{
"collectionId": "restaurants",
"queryScope": "COLLECTION",
"fields": [
{ "fieldPath": "category", "mode": "ASCENDING" },
{ "fieldPath": "numRatings", "mode": "DESCENDING" }
]
},
{
"collectionId": "restaurants",
"queryScope": "COLLECTION",
"fields": [
{ "fieldPath": "price", "mode": "ASCENDING" },
{ "fieldPath": "numRatings", "mode": "DESCENDING" }
]
},
{
"collectionId": "restaurants",
"queryScope": "COLLECTION",
"fields": [
{ "fieldPath": "city", "mode": "ASCENDING" },
{ "fieldPath": "price", "mode": "ASCENDING" }
]
},
{
"collectionId": "restaurants",
"fields": [
{ "fieldPath": "category", "mode": "ASCENDING" },
{ "fieldPath": "price", "mode": "ASCENDING" }
]
}
],
"fieldOverrides": []
}
Untuk menyebarkan indeks ini, jalankan perintah berikut:
$ firebase deploy --only firestore:indexes
Perhatikan bahwa pembuatan indeks tidak terjadi secara instan, Anda dapat memantau kemajuannya di Firebase console.
Konfigurasikan aplikasi
Dalam file util/FirestoreInitializer.kt
dan util/AuthInitializer.kt
kami mengonfigurasi Firebase SDK agar terhubung ke emulator saat dalam mode debug:
override fun create(context: Context): FirebaseFirestore {
val firestore = Firebase.firestore
// Use emulators only in debug builds
if (BuildConfig.DEBUG) {
firestore.useEmulator(FIRESTORE_EMULATOR_HOST, FIRESTORE_EMULATOR_PORT)
}
return firestore
}
Jika Anda ingin menguji aplikasi dengan proyek Firebase sebenarnya, Anda dapat:
- Bangun aplikasi dalam mode rilis dan jalankan di perangkat.
- Ganti sementara
BuildConfig.DEBUG
denganfalse
dan jalankan aplikasi lagi.
Perhatikan bahwa Anda mungkin perlu Keluar dari aplikasi dan masuk lagi agar dapat terhubung ke produksi dengan benar.