1. Genel Bakış
Hedefler
Bu codelab'de Android üzerinde Cloud Firestore tarafından desteklenen bir restoran öneri uygulaması oluşturacaksınız. Nasıl yapılacağını öğreneceksiniz:
- Bir Android uygulamasından Firestore'a veri okuma ve yazma
- Firestore verilerindeki değişiklikleri gerçek zamanlı olarak dinleyin
- Firestore verilerinin güvenliğini sağlamak için Firebase Kimlik Doğrulamasını ve güvenlik kurallarını kullanın
- Karmaşık Firestore sorguları yazın
Önkoşullar
Bu codelab'e başlamadan önce aşağıdakilere sahip olduğunuzdan emin olun:
- Android Studio Flamingo veya daha yenisi
- API 19 veya üzeri sürüme sahip bir Android emülatörü
- Node.js sürüm 16 veya üzeri
- Java sürümü 17 veya üzeri
2. Firebase projesi oluşturun
- Firebase konsolunda Google hesabınızla oturum açın.
- Firebase konsolunda Proje ekle'yi tıklayın.
- Aşağıdaki ekran görüntüsünde gösterildiği gibi Firebase projeniz için bir ad girin (örneğin, "Friendly Eats") ve Devam'ı tıklayın.
- Bu codelab'in amaçları açısından Google Analytics'i etkinleştirmeniz istenebilir, seçiminiz önemli değildir.
- Bir dakika kadar sonra Firebase projeniz hazır olacak. Devam'ı tıklayın.
3. Örnek projeyi ayarlayın
Kodu indirin
Bu codelab'in örnek kodunu kopyalamak için aşağıdaki komutu çalıştırın. Bu, makinenizde friendlyeats-android
adında bir klasör oluşturacaktır:
$ git clone https://github.com/firebase/friendlyeats-android
Makinenizde git yoksa kodu doğrudan GitHub'dan da indirebilirsiniz.
Firebase yapılandırmasını ekle
- Firebase konsolunda sol gezinme bölmesinde Projeye Genel Bakış'ı seçin. Platformu seçmek için Android düğmesine tıklayın. Paket adı istendiğinde
com.google.firebase.example.fireeats
kullanın
- Uygulamayı Kaydet'e tıklayın ve
google-services.json
dosyasını indirmek için talimatları izleyin ve dosyayı az önce indirdiğiniz kodunapp/
klasörüne taşıyın. Daha sonra İleri'ye tıklayın.
Projeyi içe aktar
Android Studio'yu açın. Dosya > Yeni > Projeyi İçe Aktar'a tıklayın ve Friendlyeats-android klasörünü seçin.
4. Firebase Emülatörlerini Kurun
Bu codelab'de, Cloud Firestore ve diğer Firebase hizmetlerini yerel olarak taklit etmek için Firebase Emulator Suite'i kullanacaksınız. Bu, uygulamanızı geliştirmek için güvenli, hızlı ve ücretsiz bir yerel geliştirme ortamı sağlar.
Firebase CLI'yi yükleyin
Öncelikle Firebase CLI'yi yüklemeniz gerekecek. MacOS veya Linux kullanıyorsanız aşağıdaki cURL komutunu çalıştırabilirsiniz:
curl -sL https://firebase.tools | bash
Windows kullanıyorsanız, bağımsız bir ikili dosya almak veya npm
aracılığıyla kurulum yapmak için kurulum talimatlarını okuyun.
CLI'yi yükledikten sonra firebase --version
çalıştırmak 9.0.0
veya üzeri bir sürümü bildirmelidir:
$ firebase --version 9.0.0
Giriş yapmak
CLI'yi Google hesabınıza bağlamak için firebase login
çalıştırın. Bu, oturum açma işlemini tamamlamak için yeni bir tarayıcı penceresi açacaktır. Daha önce Firebase projenizi oluştururken kullandığınız hesabın aynısını seçtiğinizden emin olun.
Projenizi bağlayın
friendlyeats-android
klasörü içinden, yerel projenizi Firebase projenize bağlamak için firebase use --add
komutunu çalıştırın. Daha önce oluşturduğunuz projeyi seçmek için talimatları izleyin ve bir takma ad seçmeniz istenirse default
girin.
5. Uygulamayı çalıştırın
Artık Firebase Emulator Suite'i ve FriendlyEats Android uygulamasını ilk kez çalıştırmanın zamanı geldi.
Emülatörleri çalıştırın
Terminalinizde, friendlyeats-android
dizininden firebase emulators:start
. Günlükleri şu şekilde görmelisiniz:
$ 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.
Artık makinenizde çalışan eksiksiz bir yerel geliştirme ortamınız var! Codelab'in geri kalanı boyunca bu komutu çalışır durumda bıraktığınızdan emin olun; Android uygulamanızın emülatörlere bağlanması gerekecektir.
Uygulamayı Emülatörlere bağlayın
util/FirestoreInitializer.kt
ve util/AuthInitializer.kt
dosyalarını Android Studio'da açın. Bu dosyalar, uygulama başlatıldığında Firebase SDK'larını makinenizde çalışan yerel öykünücülere bağlama mantığını içerir.
FirestoreInitializer
sınıfının create()
yönteminde şu kod parçasını inceleyin:
// Use emulators only in debug builds
if (BuildConfig.DEBUG) {
firestore.useEmulator(FIRESTORE_EMULATOR_HOST, FIRESTORE_EMULATOR_PORT)
}
Emülatörlere yalnızca uygulamamız debug
modunda çalışırken bağlandığımızdan emin olmak için BuildConfig
kullanıyoruz. Uygulamayı release
modunda derlediğimizde bu koşul yanlış olacaktır.
Firebase SDK'yı yerel Firestore öykünücüsüne bağlamak için useEmulator(host, port)
yöntemini kullandığını görebiliriz. Uygulama boyunca, FirebaseFirestore
bu örneğine erişmek için FirebaseUtil.getFirestore()
yöntemini kullanacağız, böylece debug
modunda çalışırken her zaman Firestore öykünücüsüne bağlandığımızdan emin oluruz.
Uygulamayı çalıştırın
google-services.json
dosyasını düzgün bir şekilde eklediyseniz projenin artık derlenmesi gerekir. Android Studio'da Oluştur > Projeyi Yeniden Oluştur'a tıklayın ve kalan hata olmadığından emin olun.
Android Studio'da Uygulamayı Android emülatörünüzde çalıştırın . İlk başta karşınıza "Oturum aç" ekranı çıkacak. Uygulamaya giriş yapmak için herhangi bir e-posta ve şifreyi kullanabilirsiniz. Bu oturum açma işlemi Firebase Authentication öykünücüsüne bağlanıyor, dolayısıyla hiçbir gerçek kimlik bilgisi aktarılmıyor.
Şimdi web tarayıcınızda http://localhost:4000 adresine giderek Emulators kullanıcı arayüzünü açın. Ardından Kimlik Doğrulama sekmesine tıklayın; yeni oluşturduğunuz hesabı görmelisiniz:
Oturum açma işlemini tamamladıktan sonra uygulamanın ana ekranını görmelisiniz:
Yakında ana ekranı doldurmak için bazı veriler ekleyeceğiz.
6. Firestore'a veri yazın
Bu bölümde şu anda boş olan ana ekranı doldurabilmemiz için Firestore'a bazı veriler yazacağız.
Uygulamamızdaki ana model nesnesi bir restorandır (bkz. model/Restaurant.kt
). Firestore verileri belgelere, koleksiyonlara ve alt koleksiyonlara bölünmüştür. Her restoranı bir belge olarak "restaurants"
adı verilen üst düzey bir koleksiyonda saklayacağız. Firestore veri modeli hakkında daha fazla bilgi edinmek için belgelerdeki belgeler ve koleksiyonlar hakkında bilgi edinin.
Gösterim amacıyla, taşma menüsünde "Rastgele Öğeler Ekle" düğmesini tıkladığımızda uygulamaya on rastgele restoran oluşturma işlevi ekleyeceğiz. MainFragment.kt
dosyasını açın ve onAddItemsClicked()
yöntemindeki içeriği şununla değiştirin:
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)
}
}
Yukarıdaki kodla ilgili dikkat edilmesi gereken birkaç önemli nokta vardır:
-
"restaurants"
koleksiyonuna referans alarak başladık. Koleksiyonlar, belgeler eklendiğinde örtülü olarak oluşturulur, dolayısıyla verileri yazmadan önce koleksiyonun oluşturulmasına gerek kalmaz. - Belgeler, her Restoran belgesini oluşturmak için kullandığımız Kotlin veri sınıfları kullanılarak oluşturulabilir.
-
add()
yöntemi, otomatik olarak oluşturulan kimliğe sahip bir koleksiyona bir belge ekler; böylece her Restoran için benzersiz bir kimlik belirtmemize gerek kalmaz.
Şimdi uygulamayı tekrar çalıştırın ve az önce yazdığınız kodu çağırmak için taşma menüsündeki (sağ üst köşedeki) "Rastgele Öğeler Ekle" düğmesini tıklayın:
Şimdi web tarayıcınızda http://localhost:4000 adresine giderek Emulators kullanıcı arayüzünü açın. Ardından Firestore sekmesine tıklayın; yeni eklediğiniz verileri görmelisiniz:
Bu veriler makinenize %100 yereldir. Aslında gerçek projeniz henüz bir Firestore veritabanı bile içermiyor! Bu, hiçbir sonuç doğurmadan bu verileri değiştirme ve silme denemelerinin güvenli olduğu anlamına gelir.
Tebrikler, az önce Firestore'a veri yazdınız! Bir sonraki adımda bu verilerin uygulamada nasıl görüntüleneceğini öğreneceğiz.
7. Firestore'dan verileri görüntüleyin
Bu adımda Firestore'dan nasıl veri alıp uygulamamızda görüntüleyeceğimizi öğreneceğiz. Firestore'dan veri okumanın ilk adımı bir Query
oluşturmaktır. MainFragment.kt
dosyasını açın ve onViewCreated()
yönteminin başına aşağıdaki kodu ekleyin:
// Firestore
firestore = Firebase.firestore
// Get the 50 highest rated restaurants
query = firestore.collection("restaurants")
.orderBy("avgRating", Query.Direction.DESCENDING)
.limit(LIMIT.toLong())
Şimdi sorguyu dinlemek istiyoruz, böylece eşleşen tüm belgeleri alabilir ve gelecekteki güncellemelerden gerçek zamanlı olarak haberdar olabiliriz. Nihai hedefimiz bu verileri bir RecyclerView
bağlamak olduğundan, verileri dinlemek için bir RecyclerView.Adapter
sınıfı oluşturmamız gerekir.
Kısmen uygulanmış olan FirestoreAdapter
sınıfını açın. Öncelikle bağdaştırıcının EventListener
uygulamasını sağlayalım ve Firestore sorgusuna yönelik güncellemeleri alabilmesi için onEvent
işlevini tanımlayalım:
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()
}
// ...
}
İlk yüklemede dinleyici her yeni belge için bir ADDED
olay alacaktır. Sorgunun sonuç kümesi zamanla değiştikçe dinleyici, değişiklikleri içeren daha fazla olay alacaktır. Şimdi dinleyiciyi uygulamayı bitirelim. Öncelikle üç yeni yöntem ekleyin: onDocumentAdded
, onDocumentModified
ve 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)
}
Daha sonra bu yeni yöntemleri onEvent
çağırın:
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()
}
Son olarak dinleyiciyi eklemek için startListening()
yöntemini uygulayın:
fun startListening() {
if (registration == null) {
registration = query.addSnapshotListener(this)
}
}
Artık uygulama tamamen Firestore'dan veri okuyacak şekilde yapılandırılmıştır. Uygulamayı tekrar çalıştırdığınızda önceki adımda eklediğiniz restoranları görmelisiniz:
Şimdi tarayıcınızdaki Emulator kullanıcı arayüzüne geri dönün ve restoran adlarından birini düzenleyin. Uygulamada neredeyse anında değiştiğini göreceksiniz!
8. Verileri sıralayın ve filtreleyin
Uygulama şu anda koleksiyonun tamamındaki en yüksek puan alan restoranları gösteriyor ancak gerçek bir restoran uygulamasında kullanıcı verileri sıralamak ve filtrelemek ister. Örneğin, uygulama "Philadelphia'nın en iyi deniz ürünleri restoranları" veya "En ucuz pizza"yı gösterebilmelidir.
Uygulamanın üst kısmındaki beyaz çubuğa tıkladığınızda bir filtreler iletişim kutusu açılır. Bu bölümde bu iletişim kutusunun çalışması için Firestore sorgularını kullanacağız:
MainFragment.kt
onFilter()
metodunu düzenleyelim. Bu yöntem, filtreler iletişim kutusunun çıktısını yakalamak için oluşturduğumuz yardımcı nesne olan Filters
nesnesini kabul eder. Filtrelerden bir sorgu oluşturmak için bu yöntemi değiştireceğiz:
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
}
Yukarıdaki kod parçasında, verilen filtrelerle eşleşmesi için where
ve orderBy
cümlelerini ekleyerek bir Query
nesnesi oluşturuyoruz.
Uygulamayı tekrar çalıştırın ve en popüler düşük fiyatlı restoranları göstermek için aşağıdaki filtreyi seçin:
Artık yalnızca düşük fiyatlı seçenekler içeren, filtrelenmiş bir restoran listesi görmelisiniz:
Buraya kadar başardıysanız artık Firestore'da tam işlevli bir restoran tavsiyesi görüntüleme uygulaması geliştirmişsiniz demektir! Artık restoranları gerçek zamanlı olarak sıralayabilir ve filtreleyebilirsiniz. Sonraki birkaç bölümde restoranlara incelemeler ekleyeceğiz ve uygulamaya güvenlik kuralları ekleyeceğiz.
9. Verileri alt koleksiyonlarda düzenleyin
Bu bölümde, kullanıcıların en sevdikleri (veya en az sevdikleri) restoranları inceleyebilmeleri için uygulamaya derecelendirmeler ekleyeceğiz.
Koleksiyonlar ve alt koleksiyonlar
Şu ana kadar tüm restoran verilerini "restoranlar" adı verilen üst düzey bir koleksiyonda sakladık. Bir kullanıcı bir restoranı derecelendirdiğinde, restoranlara yeni bir Rating
nesnesi eklemek istiyoruz. Bu görev için bir alt koleksiyon kullanacağız. Alt koleksiyonu, bir belgeye eklenen koleksiyon olarak düşünebilirsiniz. Yani her restoran belgesi, derecelendirme belgeleriyle dolu bir derecelendirme alt koleksiyonuna sahip olacaktır. Alt koleksiyonlar, belgelerimizi şişirmeden veya karmaşık sorgular gerektirmeden verileri düzenlemenize yardımcı olur.
Bir alt koleksiyona erişmek için ana belgede .collection()
öğesini çağırın:
val subRef = firestore.collection("restaurants")
.document("abc123")
.collection("ratings")
Bir alt koleksiyona tıpkı üst düzey bir koleksiyonda olduğu gibi erişebilir ve sorgulayabilirsiniz; boyut sınırlaması veya performans değişikliği yoktur. Firestore veri modeli hakkında daha fazla bilgiyi burada bulabilirsiniz.
Bir işlemde veri yazma
Uygun alt koleksiyona bir Rating
eklemek yalnızca .add()
öğesinin çağrılmasını gerektirir, ancak aynı zamanda yeni verileri yansıtacak şekilde Restaurant
nesnesinin ortalama derecelendirmesini ve derecelendirme sayısını da güncellememiz gerekir. Bu iki değişikliği yapmak için ayrı işlemler kullanırsak, eski veya yanlış verilere yol açabilecek bir takım yarış koşulları ortaya çıkar.
Puanların düzgün bir şekilde eklendiğinden emin olmak için bir restorana puan eklemek için bir işlem kullanacağız. Bu işlem birkaç eylem gerçekleştirecektir:
- Restoranın mevcut puanını okuyun ve yeni puanı hesaplayın
- Derecelendirmeyi alt koleksiyona ekleyin
- Restoranın ortalama puanını ve puan sayısını güncelleyin
RestaurantDetailFragment.kt
dosyasını açın ve addRating
işlevini uygulayın:
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
}
}
addRating()
işlevi, işlemin tamamını temsil eden bir Task
döndürür. onRating()
işlevinde, işlemin sonucuna yanıt vermek üzere göreve dinleyiciler eklenir.
Şimdi uygulamayı tekrar çalıştırın ve restoran detay ekranının açılması gereken restoranlardan birine tıklayın. İnceleme eklemeye başlamak için + düğmesini tıklayın. Birkaç yıldız seçip bir miktar metin girerek bir inceleme ekleyin.
Gönder tuşuna basmak işlemi başlatacaktır. İşlem tamamlandığında yorumunuzun aşağıda görüntülendiğini ve restoranın yorum sayısında bir güncelleme göreceksiniz:
Tebrikler! Artık Cloud Firestore'da oluşturulmuş sosyal, yerel, mobil bir restoran inceleme uygulamanız var. Bunların bugünlerde çok popüler olduğunu duydum.
10. Verilerinizi güvence altına alın
Şu ana kadar bu uygulamanın güvenliğini dikkate almadık. Kullanıcıların yalnızca doğru verileri okuyup yazabildiğini nasıl bilebiliriz? Firestore veritabanları, Güvenlik Kuralları adı verilen bir yapılandırma dosyasıyla korunur.
firestore.rules
dosyasını açın, aşağıdakileri görmelisiniz:
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;
}
}
}
İstenmeyen veri erişimlerini veya değişikliklerini önlemek için bu kuralları değiştirelim, firestore.rules
dosyasını açıp içeriği aşağıdakiyle değiştirelim:
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;
}
}
}
}
Bu kurallar, istemcilerin yalnızca güvenli değişiklikler yapmasını sağlamak için erişimi kısıtlar. Örneğin, bir restoran belgesinde yapılan güncellemeler yalnızca derecelendirmeleri değiştirebilir, adı veya diğer değişmez verileri değiştiremez. Derecelendirmeler yalnızca kullanıcı kimliğinin oturum açmış kullanıcıyla eşleşmesi durumunda oluşturulabilir; bu da sahteciliği önler.
Güvenlik Kuralları hakkında daha fazla bilgi edinmek için belgeleri ziyaret edin.
11. Sonuç
Artık Firestore'un üzerinde tam özellikli bir uygulama oluşturdunuz. Aşağıdakiler de dahil olmak üzere en önemli Firestore özelliklerini öğrendiniz:
- Belgeler ve koleksiyonlar
- Veri okuma ve yazma
- Sorgularla sıralama ve filtreleme
- Alt koleksiyonlar
- İşlemler
Daha fazla bilgi edin
Firestore hakkında bilgi almaya devam etmek için işte başlamanız gereken bazı iyi yerler:
Bu codelab'deki restoran uygulaması "Friendly Eats" örnek uygulamasını temel alıyordu. Söz konusu uygulamanın kaynak koduna buradan göz atabilirsiniz.
İsteğe bağlı: Üretime dağıtma
Şu ana kadar bu uygulama yalnızca Firebase Emulator Suite'i kullandı. Bu uygulamayı gerçek bir Firebase projesine nasıl dağıtacağınızı öğrenmek istiyorsanız bir sonraki adıma geçin.
12. (İsteğe bağlı) Uygulamanızı dağıtın
Şu ana kadar bu uygulama tamamen yereldi, tüm veriler Firebase Emulator Suite'te bulunuyor. Bu bölümde Firebase projenizi, bu uygulamanın üretimde çalışacak şekilde nasıl yapılandırılacağını öğreneceksiniz.
Firebase Kimlik Doğrulaması
Firebase konsolunda Kimlik Doğrulama bölümüne gidin ve Başlayın'ı tıklayın. Oturum açma yöntemi sekmesine gidin ve Yerel sağlayıcılardan E-posta/Şifre seçeneğini seçin.
E-posta/Şifreyle oturum açma yöntemini etkinleştirin ve Kaydet'i tıklayın.
Yangın deposu
Veritabanı yarat
Konsolun Firestore Veritabanı bölümüne gidin ve Veritabanı Oluştur'a tıklayın:
- Güvenlik Kurallarının Üretim Modunda başlamayı seçmesi istendiğinde, bu kuralları yakında güncelleyeceğiz.
- Uygulamanız için kullanmak istediğiniz veritabanı konumunu seçin. Veritabanı konumu seçmenin kalıcı bir karar olduğunu ve bunu değiştirmek için yeni bir proje oluşturmanız gerekeceğini unutmayın. Bir proje konumu seçme hakkında daha fazla bilgi için belgelere bakın.
Kuralları Dağıt
Daha önce yazdığınız Güvenlik Kurallarını dağıtmak için codelab dizininde aşağıdaki komutu çalıştırın:
$ firebase deploy --only firestore:rules
Bu, firestore.rules
içeriğini projenize dağıtacaktır; bunu konsoldaki Kurallar sekmesine giderek onaylayabilirsiniz.
Dizinleri Dağıt
FriendlyEats uygulaması, bir dizi özel bileşik indeks gerektiren karmaşık sıralama ve filtrelemeye sahiptir. Bunlar Firebase konsolunda elle oluşturulabilir ancak tanımlarını firestore.indexes.json
dosyasına yazmak ve Firebase CLI'yi kullanarak dağıtmak daha kolaydır.
firestore.indexes.json
dosyasını açarsanız gerekli indekslerin zaten sağlandığını göreceksiniz:
{
"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": []
}
Bu dizinleri dağıtmak için aşağıdaki komutu çalıştırın:
$ firebase deploy --only firestore:indexes
Dizin oluşturmanın anlık olmadığını unutmayın; ilerlemeyi Firebase konsolundan izleyebilirsiniz.
Uygulamayı yapılandırın
util/FirestoreInitializer.kt
ve util/AuthInitializer.kt
dosyalarında, Firebase SDK'yı hata ayıklama modundayken öykünücülere bağlanacak şekilde yapılandırdık:
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
}
Uygulamanızı gerçek Firebase projenizle test etmek isterseniz aşağıdakilerden birini yapabilirsiniz:
- Uygulamayı yayın modunda oluşturun ve bir cihazda çalıştırın.
-
BuildConfig.DEBUG
geçici olarakfalse
ile değiştirin ve uygulamayı yeniden çalıştırın.
Üretime düzgün bir şekilde bağlanmak için uygulamada Oturumu Kapatmanız ve tekrar oturum açmanız gerekebileceğini unutmayın.