Firebase ve Jetpack Compose ile Android uygulaması geliştirme

1. Giriş

Son Güncelleme: 16.11.2022

Firebase ve Jetpack Compose ile Android uygulaması geliştirme

Bu kod laboratuvarında, Make It So adlı bir Android uygulaması oluşturacaksınız. Bu uygulamanın kullanıcı arayüzü tamamen Android'in yerel kullanıcı arayüzü oluşturmaya yönelik modern araç seti olan Jetpack Compose ile oluşturulmuştur. Sezgisel olan bu araç seti, .xml dosyaları yazıp bunları 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şturacağınız uygulama

Make It So, 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.

Görev Ekle ekranı Ana ekran olarak ayarla

Bu uygulamada eksik olan bazı özellikleri eklersiniz:

  • E-posta ve şifreyle kullanıcı kimliklerini doğrulama
  • Firestore koleksiyonuna bir dinleyici 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 bunu kullanıma sunmak için aşamalı kullanıma sunma özelliğini 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

2. Örnek uygulamayı indirip Firebase'i ayarlama

Ö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 projesi oluşturma

Yapmanız gereken ilk şey, Firebase konsoluna gidip "+ Proje ekle" düğmesini tıklayarak bir Firebase projesi oluşturmaktır. Örnek:

Firebase konsolu

Proje oluşturma işlemini tamamlamak için ekrandaki adımları uygulayın.

Firebase projenize Android uygulaması ekleme

Firebase projenize farklı uygulamalar kaydedebilirsiniz: Android, iOS, Web, Flutter ve Unity için.

Burada gördüğünüz gibi Android seçeneğini belirleyin:

Firebase Projesine Genel Bakış

Ardından aşağıdaki adımları uygulayın:

  1. Paket adı olarak com.example.makeitso ve isteğe bağlı olarak bir takma ad girin. Bu codelab için hata ayıklama imzalama sertifikası eklemeniz gerekmez.
  2. Uygulamanızı kaydetmek ve Firebase yapılandırma dosyasına erişmek için Sonraki'yi tıklayın.
  3. Yapılandırma dosyanızı indirip make-it-so-android/app dizinine kaydetmek için google-services.json dosyasını indir'i tıklayın.
  4. İ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.
  5. İşlemi tamamlamak için Konsol'a 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.

Kimlik Doğrulama'yı ayarlama

Öncelikle, kullanıcıların uygulamaya giriş yapabilmesi için Kimlik doğrulamayı etkinleştirelim:

  1. Build (Derleme) menüsünde, Authentication'ı (Kimlik Doğrulama) seçin ve Get Started (Başlayın) seçeneğini tıklayın.
  2. Oturum açma yöntemi kartında E-posta/Şifre'yi seçin ve etkinleştirin.
  3. Ardından Yeni sağlayıcı ekle'yi tıklayın ve Anonim'i seçip etkinleştirin.

Cloud Firestore'u ayarlama

Ardından Firestore'u ayarlayın. Oturum açmış bir kullanıcının görevlerini saklamak için Firestore'u kullanırsınız. Her kullanıcı, veritabanının bir koleksiyonu içinde kendi dokümanını alır.

  1. Firebase konsolunun sol panelinde Derleme'yi genişletin ve ardından Firestore veritabanı'nı seçin.
  2. Create database'i (Veritabanı oluştur) tıklayın.
  3. Veritabanı Kimliği değerini (default) olarak bırakın.
  4. Veritabanınız için bir konum seçip İleri'yi tıklayın.
    Gerçek bir uygulama için kullanıcılarınıza yakın bir konum seçmeniz gerekir.
  5. Test modunda başlat'ı tıklayın. Güvenlik kurallarıyla ilgili sorumluluk reddi beyanını okuyun.
    Bu bölümün sonraki adımlarında, verilerinizi korumak için güvenlik kuralları ekleyeceksiniz. Veritabanınıza Güvenlik Kuralları eklemeden bir uygulamayı dağıtmayın veya herkese açık olarak göstermeyin.
  6. Oluştur'u tıklayın.

Şimdi de Firestore veritabanı için sağlam Güvenlik Kuralları oluşturalım.

  1. Firestore kontrol panelini açıp Kurallar sekmesine gidin.
  2. 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çmış olan tüm kullanıcıların herhangi bir koleksiyonda kendileri için bir doküman oluşturabileceğini belirtir. Ardından, oluşturulan dokümanı yalnızca dokümanı oluşturan kullanıcı 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 Emulator veya gerçek bir Android cihaz kullanılabilir).

3. Firebase Authentication

Hangi özelliği ekliyorsunuz?

Make It So örnek uygulamasının mevcut durumunda, kullanıcı oturum açmak zorunda kalmadan uygulamayı kullanmaya başlayabilir. Bunu yapmak için anonim kimlik doğrulamayı 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 e-posta ve şifre yazarak hesap oluşturduğunda Firebase Authentication API'den e-posta kimlik bilgisi istemeniz ve ardından yeni kimlik bilgisini anonim hesaba bağlamanız gerekir. Android Studio'da AccountServiceImpl.kt dosyasını 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 dosyasını açın ve onSignUpClick işlevinin launchCatching bloğunda linkAccount hizmet işlevini çağırın:

screen/sign_up/SignUpViewModel.kt

launchCatching {
    accountService.linkAccount(email, password)
    openAndPopUp(SETTINGS_SCREEN, SIGN_UP_SCREEN)
}

Önce kimlik doğrulamaya çalışır ve çağrı başarılı olursa bir sonraki ekrana (SettingsScreen) geçer. Bu çağrıları bir launchCatching bloğunun içinde yürüttüğünüz için ilk satırda bir hata meydana gelirse istisna yakalanır ve ele alınır ve ikinci satıra hiç 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.

screens/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 çalıştırın ve ekranın sağ üst köşesindeki dişli simgesini tıklayarak ayarlara gidin. Buradan hesap oluşturma seçeneğini tıklayın:

Make it So ayarları ekranı Öyle olsun kayıt ekranı

Hesabınızı oluşturmak için geçerli bir e-posta adresi 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. Kullanıcılar sekmesini tıklayarak Firebase konsolundaki Kimlik Doğrulama kontrol panelinde oluşturulan yeni hesabı kontrol edebilirsiniz.

4. Cloud Firestore

Hangi özelliği ekleyeceksiniz?

Cloud Firestore için, Make it So'da gösterilen görevleri temsil eden belgeleri depolayan Firestore koleksiyonuna bir dinleyici eklersiniz. Bu dinleyiciyi ekledikten sonra, bu koleksiyonda yapılan her güncellemeyi 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 bir doküman ile temsil edilir ve her birinin userId adlı bir 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çindeki composable function'ün bu akıştan haberdar olmasını ve durumu bir durum olarak toplamasını sağlayın. Durum her değiştiğinde, derlenebilir işlev 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())

Kompozit işlev bu durumlara eriştikten sonra LazyColumn'ü (ekranda liste görüntülemek için kullandığınız yapı) şu şekilde güncelleyebilirsiniz:

screens/tasks/TasksScreen.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 Make it So'ya giriş yaparsanız yapılacaklar listenizi düzenleyebilir ve tüm cihazlarda anlık olarak güncellenmesini izleyebilirsiniz.

5. Performance Monitoring

Hangi özelliği ekliyorsunuz?

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ı olur. 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 hangi bölümlerinin ölçülmesinin önemli olduğunu düşündüğünüzü seçebilir ve bu bölümlere özel izler ekleyebilirsiniz. Aşağıda, bu kod laboratuvarının önceki bölümünde (AccountServiceImpl.kt içinde) gördüğünüz linkAccount işlevine özel bir izleme ekleme örneği verilmiştir:

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 uygulamasına bazı özel izler ekleyin ve beklenen şekilde çalışıp çalışmadığını test etmek için bir sonraki bölüme geçin.

Test etme zamanı

Özel izlemeleri eklemeyi tamamladıktan 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 kısmında üç sekme bulunur: Ağ istekleri, Özel izlemeler 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 ekliyorsunuz?

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 kod laboratuvarında, Make it So uygulamasında yeni görevi düzenle ö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:

Remote Config Parametre Oluştur iletişim kutusu

Tüm alanlar doldurulduktan sonra Save (Kaydet) düğmesini ve ardından Publish'i (Yayınla) tıklayabilirsiniz. Parametre oluşturulup kod tabanınızda kullanılabilir hale geldiğine göre, yeni değerleri getirecek kodu uygulamanıza eklemeniz gerekir. ConfigurationServiceImpl.kt dosyasını açıp bu iki işlevin uygulanması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 SplashViewModel.kt işlevinde bu işlev, uygulama başlar başlamaz ç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ğıdakileri ekleyerek bu bilgileri TasksViewModel.kt içinde 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. Bu nedenle, TasksScreen.kt dosyasını açıp LazyColum öğesini TasksViewModel.kt'de bulunan seçenekleri 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 belirten başka bir composable function öğesidir. Ayrıca her görevin sonunda, kullanıcı üç nokta simgesini tıkladığında gösterilen seçenekler menüsü bulunur.

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şip eşleşmediğini kontrol edin:

  • 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;

Console'da değeri birkaç kez değiştirmeyi ve uygulamayı yeniden başlatmayı deneyin. Remote Config'i kullanarak uygulamanızda yeni özellikler yayınlamak işte bu kadar kolaydır.

7. Tebrikler

Tebrikler, Firebase ve Jetpack Compose ile başarıyla bir Android uygulaması geliştirdiniz.

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

Referans dokümanları