1. Giriş
Son Güncelleme: 16.11.2022
Firebase ve Jetpack Compose ile Android uygulaması geliştirme
Bu codelab'de Make It So adlı bir Android uygulaması geliştireceksiniz. Bu uygulamanın kullanıcı arayüzü tamamen Jetpack Compose ile oluşturulmuştur. Android'in yerel kullanıcı arayüzü oluşturmaya yönelik modern araç seti olan bu uygulama sezgiseldir ve .xml dosyaları yazıp Etkinliklere, Parçalara veya Görünümlere bağlamaktan daha az kod gerektirir.
Firebase ve Jetpack Compose'un birlikte ne kadar iyi çalıştığını anlamanın ilk adımı, modern Android mimarisini anlamaktır. İyi bir mimari, bileşenlerin nasıl düzenlendiğini ve birbirleriyle iletişim kurduklarını çok açık hale getirdiği için sistemin anlaşılmasını, geliştirilmesini ve bakımını kolaylaştırır. Android dünyasında, önerilen mimari Model - View - ViewModel olarak adlandırılır. Model, uygulamadaki Verilere erişen katmanı temsil eder. Görünüm, kullanıcı arayüzü katmanıdır ve iş mantığı hakkında hiçbir şey bilmemelidir. ViewModel, iş mantığının uygulandığı yerdir. Bu da bazen ViewModel'in Model katmanını çağırmasını gerektirir.
Kod tabanının anlaşılmasını ve sonraki adımların tamamlanmasını kolaylaştıracağı için Model - View - ViewModel'in Jetpack Compose ile oluşturulan bir Android uygulamasına nasıl uygulandığını anlamak için bu makaleyi okumanızı önemle tavsiye ederiz.
Oluşturacaklarınız
Yapılacaklar Listesi, kullanıcının görev ekleyip düzenlemesine, bayraklar, öncelikler ve son tarihler eklemesine ve görevleri tamamlandı olarak işaretlemesine olanak tanıyan basit bir yapılacaklar listesi uygulamasıdır. Aşağıdaki resimlerde bu uygulamanın iki ana sayfası gösterilmektedir: Görev oluşturma sayfası ve oluşturulan görevlerin listesinin yer aldığı ana sayfa.
Bu uygulamada bulunmayan bazı özellikleri ekleyeceksiniz:
- Kullanıcıların kimliğini e-posta ve şifreyle doğrulama
- Firestore koleksiyonuna işleyici ekleme ve kullanıcı arayüzünün değişikliklere tepki vermesini sağlama
- Uygulamadaki belirli bir kodun performansını izlemek için özel izler ekleyin.
- Remote Config'i kullanarak bir özellik açma/kapatma düğmesi oluşturun ve özelliği başlatmak için aşamalı sunumu kullanın
Neler öğreneceksiniz?
- Modern Android uygulamasında Firebase Authentication, Performance Monitoring, Remote Config ve Cloud Firestore'u kullanma
- Firebase API'lerini MVVM mimarisine uygun hâle getirme
- Firebase API'leriyle yapılan değişiklikleri Compose kullanıcı arayüzünde yansıtma
Gerekenler
- Android Studio Flamingo+
- API 21 veya sonraki sürümlere sahip Android Emulator
- Kotlin programlama dili hakkında bilgi
2. Örnek uygulamayı indirin ve Firebase'i kurun
Örnek uygulamanın kodunu alma
GitHub deposunu komut satırından klonlayın:
git clone https://github.com/FirebaseExtended/make-it-so-android.git
Firebase'i ayarlama
İlk yapmanız gereken, Firebase konsoluna gitmek ve "+ Proje ekle"yi tıklayarak bir Firebase projesi oluşturmaktır. aşağıdaki gibi düğmeyi tıklayın:
Proje oluşturma işlemini tamamlamak için ekrandaki adımları uygulayın.
Her Firebase projesinde Android, iOS, Web, Flutter ve Unity için farklı uygulamalar oluşturabilirsiniz. Burada gördüğünüz gibi Android seçeneğini belirleyin:
Ardından aşağıdaki adımları uygulayın:
- Paket adı olarak
com.example.makeitso
yazın ve isteğe bağlı olarak bir takma ad girin. Bu codelab için hata ayıklama imzalama sertifikasını eklemeniz gerekmez. - Uygulamanızı kaydetmek ve Firebase yapılandırma dosyasına erişmek için Sonraki'yi tıklayın.
- Yapılandırma dosyanızı indirmek ve
make-it-so-android/app
dizinine kaydetmek için Google-services.json dosyasını indir'i tıklayın. - İleri'yi tıklayın. Firebase SDK'ları örnek projedeki
build.gradle
dosyasına zaten dahil edildiğinden Sonraki'yi tıklayarak Sonraki adımlar'a geçin. - İşlemi tamamlamak için Konsola devam et'i tıklayın.
Make it So uygulamasının düzgün çalışması için, koda geçmeden önce Console'da iki şey yapmanız gerekir: Kimlik doğrulama sağlayıcılarını etkinleştirin ve Firestore veritabanını oluşturun. Öncelikle, kullanıcıların uygulamaya giriş yapabilmesi için Kimlik doğrulamayı etkinleştirelim:
- Build (Derleme) menüsünde, Authentication'ı (Kimlik Doğrulama) seçin ve Get Started (Başlayın) seçeneğini tıklayın.
- Oturum açma yöntemi kartında E-posta/Şifre'yi seçin ve etkinleştirin.
- Ardından Yeni sağlayıcı ekle'yi tıklayın ve Anonim'i seçip etkinleştirin.
Sonra, Firestore'u kurun. Oturum açmış kullanıcıların görevlerini depolamak için Firestore kullanılır. Her kullanıcı, veritabanının bir koleksiyonunda kendi dokümanını alır.
- Derleme menüsünden Firestore'u seçip Veritabanı oluştur'u tıklayın.
- Üretim modunda başlat'ı etkin durumda tutun ve İleri'yi tıklayın.
- İstendiğinde Cloud Firestore verilerinizin depolanacağı konumu seçin. Bir üretim uygulaması geliştirirken bunun, kullanıcılarınızın çoğuna yakın bir bölgede ve Functions gibi diğer Firebase hizmetlerinde ortak bir yerde olmasını istersiniz. Bu codelab için varsayılan bölgeyi koruyabilir veya size en yakın bölgeyi seçebilirsiniz.
- Firestore veritabanınızı sağlamak için Etkinleştir'i tıklayın.
Şimdi de Firestore veritabanı için sağlam Güvenlik Kuralları oluşturalım. Firestore kontrol panelini açıp Kurallar sekmesine gidin. Ardından, Güvenlik Kurallarını aşağıdaki gibi güncelleyin:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow create: if request.auth != null;
allow read, update, delete: if request.auth != null && resource.data.userId == request.auth.uid;
}
}
}
Bu kurallar temel olarak, uygulamada oturum açan her kullanıcının herhangi bir koleksiyonda kendisi için doküman oluşturabilmesini sağlar. Doküman oluşturulduktan sonra yalnızca söz konusu dokümanı oluşturan kullanıcı dokümanı görüntüleyebilir, güncelleyebilir veya silebilir.
Uygulamayı çalıştırma
Artık uygulamayı çalıştırmaya hazırsınız. Android Studio'da make-it-so-android/start
klasörünü açın ve uygulamayı çalıştırın (Android Emülatör veya gerçek bir Android cihaz kullanarak yapılabilir).
3. Firebase Authentication
Hangi özelliği ekleyeceksiniz?
Make It So örnek uygulamasının mevcut durumunda, kullanıcı oturum açmak zorunda kalmadan uygulamayı kullanmaya başlayabilir. Bunun için anonim kimlik doğrulama kullanır. Ancak anonim hesaplar, kullanıcının başka cihazlarda veya gelecekteki oturumlarda verilerine erişmesine izin vermez. Anonim kimlik doğrulama, hazır durumda ilk katılım için kullanışlı olsa da kullanıcılara her zaman farklı bir oturum açma formuna dönüştürme seçeneği sunmalısınız. Bu doğrultuda, bu codelab'de Make It So uygulamasına e-posta ve şifreyle kimlik doğrulaması ekleyeceksiniz.
Kodlama zamanı!
Kullanıcı bir hesap oluşturur oluşturmaz, e-posta ve şifre yazarak Firebase Authentication API'den e-posta kimlik bilgilerini istemeniz ve yeni kimlik bilgisini anonim hesaba bağlamanız gerekir. AccountServiceImpl.kt
dosyasını Android Studio'da açın ve linkAccount
işlevini aşağıdaki gibi güncelleyin:
model/service/impl/AccountServiceImpl.kt
override suspend fun linkAccount(email: String, password: String) {
val credential = EmailAuthProvider.getCredential(email, password)
auth.currentUser!!.linkWithCredential(credential).await()
}
Şimdi SignUpViewModel.kt
öğesini açın ve onSignUpClick
işlevinin launchCatching
bloğundaki linkAccount
hizmetini çağırın:
screen/sign_up/SignUpViewModel.kt
launchCatching {
accountService.linkAccount(email, password)
openAndPopUp(SETTINGS_SCREEN, SIGN_UP_SCREEN)
}
Öncelikle kimlik doğrulamasını yapmaya çalışır ve arama başarılı olursa sonraki ekrana (SettingsScreen
) geçer. Bu çağrıları bir launchCatching
bloğu içinde yürütürken, ilk satırda bir hata oluşursa istisna yakalanıp işlenir ve ikinci satıra hiçbir şekilde ulaşılmaz.
SettingsScreen
tekrar açılır açılmaz, kullanıcının kimliği zaten doğrulandığından Oturum aç ve Hesap oluştur seçeneklerinin kaybolduğundan emin olmanız gerekir. Bunu yapmak için hesabın anonim olup olmadığını kontrol etmek üzere SettingsViewModel
öğesinin, geçerli kullanıcının durumunu dinlemesini (AccountService.kt
ürününde mevcuttur) sağlayalım. Bunun için SettingsViewModel.kt
içindeki uiState
öğesini aşağıdaki gibi güncelleyin:
screen/settings/SettingsViewModel.kt
val uiState = accountService.currentUser.map {
SettingsUiState(it.isAnonymous)
}
Yapmanız gereken son işlem, SettingsViewModel
tarafından yayınlanan durumları toplamak için SettingsScreen.kt
içindeki uiState
öğesini güncellemektir.
screen/settings/SettingsScreen.kt
val uiState by viewModel.uiState.collectAsState(
initial = SettingsUiState(false)
)
Artık kullanıcı her değiştiğinde SettingsScreen
, seçenekleri kullanıcının yeni kimlik doğrulama durumuna göre görüntülemek için kendini yeniden oluşturacak.
Test etme zamanı
Make it so'yu (Öyleyse yap) çalıştırın ve ekranın sağ üst köşesindeki dişli simgesini tıklayarak ayarlara gidin. Buradan hesap oluştur seçeneğini tıklayın:
Hesabınızı oluşturmak için geçerli bir e-posta ve güçlü bir şifre yazın. Bağlantı işlemi çalışır. Oturumu kapatma ve hesabınızı silme olmak üzere iki yeni seçenek göreceğiniz ayarlar sayfasına yönlendirilirsiniz. Firebase konsolundaki Authentication kontrol panelinde oluşturulan yeni hesabı Kullanıcılar sekmesini tıklayarak kontrol edebilirsiniz.
4. Cloud Firestore
Hangi özelliği ekleyeceksiniz?
Cloud Firestore için Firestore koleksiyonuna, Yapılacak İş bölümünde gösterilen görevleri temsil eden belgelerin depolandığı bir işleyici eklemeniz gerekir. Bu işleyiciyi eklediğinizde koleksiyonda yapılan tüm güncellemeleri alırsınız.
Kodlama zamanı!
StorageServiceImpl.kt
uygulamasında bulunan Flow
öğesini aşağıdaki gibi güncelleyin:
model/service/impl/StorageServiceImpl.kt
override val tasks: Flow<List<Task>>
get() =
auth.currentUser.flatMapLatest { user ->
firestore.collection(TASK_COLLECTION).whereEqualTo(USER_ID_FIELD, user.id).dataObjects()
}
Bu kod, user.id
temel alınarak görev koleksiyonuna bir işleyici ekliyor. Her görev, tasks
adlı bir koleksiyondaki dokümanla temsil edilir ve her görevin userId
adlı alanı vardır. currentUser
durumu değişirse (örneğin, çıkış yaparak) yeni bir Flow
gönderileceğini unutmayın.
Şimdi TasksViewModel.kt
içindeki Flow
öğesinin hizmettekilerle aynı olmasını sağlamanız gerekiyor:
ekranlar/görevler/GörevlerViewModel.kt
val tasks = storageService.tasks
Son olarak, kullanıcı arayüzünü temsil eden TasksScreens.kt
içinde composable function
öğesini yapmak, bu akıştan haberdar olmak ve bir durum olarak toplamaktır. Durum her değiştiğinde, composable işlevi otomatik olarak kendini yeniden oluşturur ve kullanıcıya en son durumu gösterir. Bunu TasksScreen composable function
bölümüne ekleyin:
ekranlar/görevler/GörevlerEkranı.kt
val tasks = viewModel
.tasks
.collectAsStateWithLifecycle(emptyList())
composable işlevi bu durumlara erişim elde ettikten sonra, LazyColumn
öğesini (listeyi ekranda görüntülemek için kullandığınız yapı) şu şekilde güncelleyebilirsiniz:
ekranlar/görevler/GörevlerEkranı.kt
LazyColumn {
items(tasks.value, key = { it.id }) { taskItem ->
TaskItem( [...] )
}
}
Test etme zamanı
İşe yarayıp yaramadığını test etmek için uygulamayı kullanarak (ekranın sağ alt köşesindeki ekle düğmesini tıklayarak) yeni bir görev ekleyin. Görev, oluşturulduktan sonra Firestore Konsolu'ndaki Firestore koleksiyonunda görünür. Aynı hesapla diğer cihazlarda Yapılacak İş'e giriş yaparsanız yapılacak işlerinizi düzenleyebilir ve tüm cihazlarda gerçek zamanlı olarak güncellenmelerini izleyebilirsiniz.
5. Performance Monitoring
Hangi özelliği ekleyeceksiniz?
Performansın iyi olmaması ve kullanıcıların uygulamanızı kullanarak basit bir işi tamamlamaları çok fazla zaman gerektirmesi nedeniyle, kullanıcıların uygulamanızı kullanmaktan vazgeçme olasılıkları yüksektir. Bu nedenle performansa dikkat etmek önemlidir. Bu nedenle bazen bir kullanıcının uygulamanızda izlediği belirli bir yolculukla ilgili bazı metrikleri toplamak yararlı olabilir. Firebase Performance Monitoring, size bu konuda yardımcı olmak için özel izler sunar. Yapılacak İş bölümünde özel izler eklemek ve performansı farklı kod parçalarında ölçmek için sonraki adımları uygulayın.
Kodlama zamanı!
Performance.kt
dosyasını açarsanız trace adlı bir satır içi işlev görürsünüz. Bu işlev, iz adını parametre olarak ileterek özel bir iz oluşturmak için Performance Monitoring API'yi çağırır. Gördüğünüz diğer parametre, izlemek istediğiniz kod bloğudur. Her iz için toplanan varsayılan metrik, tamamen çalıştırılma süresidir:
model/service/Performance.kt
inline fun <T> trace(name: String, block: Trace.() -> T): T = Trace.create(name).trace(block)
Kod tabanının ölçülmesinin önemli olduğunu düşündüğünüz hangi bölümlerini seçebilir ve bu bölümlere özel izler ekleyebilirsiniz. Bu codelab'de daha önce (AccountServiceImpl.kt
ürününde) gördüğünüz linkAccount
işlevine özel iz eklemeye dair bir örneği aşağıda bulabilirsiniz:
model/service/impl/AccountServiceImpl.kt
override suspend fun linkAccount(email: String, password: String): Unit =
trace(LINK_ACCOUNT_TRACE) {
val credential = EmailAuthProvider.getCredential(email, password)
auth.currentUser!!.linkWithCredential(credential).await()
}
Şimdi sıra sizde! Make it So (Öyleyse Yap) uygulamasına birkaç özel izler ekleyin ve beklendiği gibi çalışıp çalışmadığını test etmek için bir sonraki bölüme geçin.
Test etme zamanı
Özel izleri eklemeyi bitirdikten sonra uygulamayı çalıştırın ve ölçmek istediğiniz özellikleri birkaç kez kullandığınızdan emin olun. Ardından, Firebase konsoluna ve Performans kontrol paneli'ne gidin. Ekranın altında üç sekme görürsünüz: Ağ istekleri, Özel izler ve Ekran oluşturma.
Özel izler sekmesine giderek kod tabanına eklediğiniz izlerin burada gösterildiğinden ve bu kod parçalarını yürütmek için genellikle ne kadar zaman gerektiğini kontrol edin.
6. Remote Config
Hangi özelliği ekleyeceksiniz?
Remote Config'in, uygulamanızın görünümünü uzaktan değiştirmekten farklı kullanıcı segmentleri için farklı davranışlar yapılandırmaya kadar çok çeşitli kullanım alanları vardır. Bu codelab'de, Yapılacak İş uygulamasındaki yeni görev düzenleme özelliğini gösterecek veya gizleyecek bir özellik açma/kapatma düğmesi oluşturmak için Remote Config'i kullanacaksınız.
Kodlama zamanı!
İlk yapmanız gereken, Firebase konsolunda yapılandırmayı oluşturmaktır. Bunu yapmak için Remote Config kontrol paneline giderek Parametre ekle düğmesini tıklamanız gerekir. Alanları aşağıdaki resme göre doldurun:
Tüm alanlar doldurulduktan sonra Save (Kaydet) düğmesini ve ardından Publish'i (Yayınla) tıklayabilirsiniz. Parametre oluşturulduğuna ve kod tabanınızda kullanılabildiğine göre, yeni değerleri uygulamanıza getirecek kodu eklemeniz gerekir. ConfigurationServiceImpl.kt
dosyasını açın ve şu iki işlevin uygulama ayarlarını güncelleyin:
model/service/impl/ConfigurationServiceImpl.kt
override suspend fun fetchConfiguration(): Boolean {
return remoteConfig.fetchAndActivate().await()
}
override val isShowTaskEditButtonConfig: Boolean
get() = remoteConfig[SHOW_TASK_EDIT_BUTTON_KEY].asBoolean()
İlk işlev, değerleri sunucudan getirir ve uygulama başlar başlamaz SplashViewModel.kt
işlevinde çağrılır. En güncel değerlerin en başından itibaren tüm ekranlarda bulunmasını sağlamanın en iyi yoludur. Daha sonra kullanıcı bir şeyler yaparken uygulamanın arayüzünü veya davranışını değiştirirseniz iyi bir kullanıcı deneyimi olmaz.
İkinci işlev, Console'da az önce oluşturduğunuz parametre için yayınlanan boole değerini döndürür. Ayrıca loadTaskOptions
işlevine aşağıdakini ekleyerek bu bilgileri TasksViewModel.kt
biçiminde almanız gerekir:
ekranlar/görevler/GörevlerViewModel.kt
fun loadTaskOptions() {
val hasEditOption = configurationService.isShowTaskEditButtonConfig
options.value = TaskActionOption.getOptions(hasEditOption)
}
İlk satırdaki değeri alıyor ve ikinci satırdaki görev öğelerine ilişkin menü seçeneklerini yüklemek için bu değeri kullanıyorsunuz. Değer false
ise menüde düzenleme seçeneği bulunmaz. Artık seçenekler listeniz olduğuna göre, kullanıcı arayüzünün bu listeyi doğru bir şekilde görüntülemesi gerekir. Jetpack Compose ile uygulama oluştururken TasksScreen
kullanıcı arayüzünün nasıl görünmesi gerektiğini açıklayan composable function
öğesini bulmanız gerekir. TasksScreen.kt
dosyasını açın ve LazyColum
dosyasını, TasksViewModel.kt
içinde sunulan seçeneklere işaret edecek şekilde güncelleyin:
ekranlar/görevler/GörevlerEkranı.kt
val options by viewModel.options
LazyColumn {
items(tasks.value, key = { it.id }) { taskItem ->
TaskItem(
options = options,
[...]
)
}
}
TaskItem
, tek bir görevin kullanıcı arayüzünün nasıl görünmesi gerektiğini açıklayan bir diğer composable function
öğesidir. Her görevde, kullanıcı görevin sonundaki üç nokta simgesini tıkladığında görüntülenen seçeneklerin bulunduğu bir menü vardır.
Test etme zamanı
Artık uygulamayı çalıştırmaya hazırsınız. Firebase konsolunu kullanarak yayınladığınız değerin, uygulamanın davranışıyla eşleştiğinden emin olun:
- Adresiniz
false
ise üç nokta simgesini tıkladığınızda yalnızca iki seçenek görürsünüz; - Adresiniz
true
ise üç nokta simgesini tıkladığınızda üç seçenek görürsünüz;
Değeri Console'da birkaç kez değiştirip uygulamayı yeniden başlatmayı deneyin. Remote Config'i kullanarak uygulamanızda yeni özellikleri başlatmak işte bu kadar kolay!
7. Tebrikler
Tebrikler, Firebase ve Jetpack Compose ile başarıyla bir Android uygulaması oluşturdunuz.
Kullanıcı arayüzü için tamamen Jetpack Compose ile oluşturulmuş bir Android uygulamasına Firebase Authentication, Performance Monitoring, Remote Config ve Cloud Firestore'u eklediniz ve bunu önerilen MVVM mimarisine uygun hale getirdiniz.
Daha fazla bilgi
- Firebase ve Compose ile Android uygulaması geliştirme
- Jetpack Compose uygulamasına Firebase Authentication ekleme
- Jetpack Compose uygulamasına Cloud Firestore ekleme
- Firebase ve Compose ile oluşturulmuş Android uygulamasına eş yordamlar ve akış ekleme
- Jetpack Compose uygulamasına Firebase Performance Monitoring ekleme
- Jetpack Compose uygulamasına Firebase Remote Config ekleme