Mem-build aplikasi Android dengan Firebase dan Jetpack Compose

1. Pengantar

Terakhir diperbarui: 16-11-2022

Mem-build aplikasi Android dengan Firebase dan Jetpack Compose

Dalam codelab ini, Anda akan mem-build aplikasi Android bernama Buat Jadi. UI aplikasi ini sepenuhnya dibuat dengan Jetpack Compose, yang merupakan toolkit modern Android untuk membangun UI native. Aplikasi ini intuitif dan memerlukan lebih sedikit kode daripada menulis file .xml dan mengikatnya ke Activity, Fragment, atau View.

Langkah pertama untuk memahami seberapa baik Firebase dan Jetpack Compose bekerja sama adalah memahami arsitektur Android modern. Arsitektur yang baik membuat sistem mudah dipahami, mudah dikembangkan, dan mudah dikelola, karena membuat sangat jelas bagaimana komponen diatur dan berkomunikasi satu sama lain. Dalam dunia Android, arsitektur yang direkomendasikan disebut Model - View - ViewModel. Model mewakili lapisan yang mengakses Data di aplikasi. Tampilan adalah lapisan UI dan tidak perlu mengetahui logika bisnis. Dan ViewModel adalah tempat logika bisnis diterapkan, yang terkadang memerlukan ViewModel untuk memanggil lapisan Model.

Sebaiknya baca artikel ini untuk memahami cara penerapan Model - View - ViewModel ke aplikasi Android yang dibuat dengan Jetpack Compose, karena akan membuat codebase lebih mudah dipahami dan langkah berikutnya lebih mudah diselesaikan.

Hal yang akan Anda build

Make It So adalah aplikasi daftar tugas sederhana yang memungkinkan pengguna menambahkan dan mengedit tugas, menambahkan tanda, prioritas, dan batas waktu, serta menandai tugas sebagai selesai. Gambar di bawah menampilkan dua halaman utama aplikasi ini: halaman pembuatan tugas dan halaman utama dengan daftar tugas yang dibuat.

Layar Make it So Add Task Jadikan Layar Utama

Anda akan menambahkan beberapa fitur yang tidak ada di aplikasi ini:

  • Mengautentikasi pengguna dengan email dan sandi
  • Menambahkan pemroses ke koleksi Firestore dan membuat UI bereaksi terhadap perubahan
  • Menambahkan trace kustom untuk memantau performa kode tertentu dalam aplikasi
  • Buat tombol fitur menggunakan Remote Config dan gunakan peluncuran bertahap untuk meluncurkannya

Yang akan Anda pelajari

  • Cara menggunakan Firebase Authentication, Performance Monitoring, Remote Config, dan Cloud Firestore dalam aplikasi Android modern
  • Cara menyesuaikan Firebase API dengan arsitektur MVVM
  • Cara mencerminkan perubahan yang dibuat dengan Firebase API di UI Compose

Yang Anda butuhkan

2. Mendapatkan aplikasi contoh dan menyiapkan Firebase

Mendapatkan kode aplikasi contoh

Clone repositori GitHub dari command line:

git clone https://github.com/FirebaseExtended/make-it-so-android.git

Siapkan Firebase

Hal pertama yang perlu Anda lakukan adalah membuka Firebase console dan membuat project Firebase dengan mengklik tombol "+ Tambahkan project", seperti yang dapat Anda lihat di bawah ini:

Firebase console

Ikuti langkah-langkah di layar untuk menyelesaikan pembuatan project.

Di dalam setiap project Firebase, Anda dapat membuat aplikasi yang berbeda: untuk Android, iOS, Web, Flutter, dan Unity. Pilih opsi Android, seperti yang Anda lihat di sini:

Ringkasan Project Firebase

Lalu, ikuti langkah-langkah berikut:

  1. Masukkan com.example.makeitso sebagai nama paket dan, jika perlu, masukkan nama panggilan. Untuk codelab ini, Anda tidak perlu menambahkan sertifikat penandatanganan debug.
  2. Klik Next untuk mendaftarkan aplikasi Anda dan mengakses file konfigurasi Firebase.
  3. Klik Download google-services.json untuk mendownload file konfigurasi dan simpan di direktori make-it-so-android/app.
  4. Klik Berikutnya. Karena Firebase SDK sudah disertakan dalam file build.gradle di project contoh, klik Next untuk langsung melanjutkan ke Langkah berikutnya.
  5. Klik Lanjutkan ke konsol untuk menyelesaikan.

Agar aplikasi Make it So berfungsi dengan baik, ada dua hal yang perlu Anda lakukan di Konsol sebelum beralih ke kode: aktifkan penyedia autentikasi dan buat database Firestore. Pertama, mari kita aktifkan Autentikasi agar pengguna dapat login ke aplikasi:

  1. Dari menu Build, pilih Authentication, lalu klik Get Started.
  2. Dari kartu Sign-in method, pilih Email/Password, lalu aktifkan.
  3. Berikutnya, klik Add new provider, lalu pilih dan aktifkan Anonymous.

Selanjutnya, siapkan Firestore. Anda akan menggunakan Firestore untuk menyimpan tugas pengguna yang login. Setiap pengguna akan mendapatkan dokumen mereka sendiri dalam koleksi database.

  1. Dari menu Build, pilih Firestore, lalu klik Create database.
  2. Tetap aktifkan Mulai dalam mode produksi, lalu klik Berikutnya.
  3. Saat diminta, pilih lokasi penyimpanan data Cloud Firestore Anda. Saat mengembangkan aplikasi produksi, Anda perlu berada di region yang dekat dengan sebagian besar pengguna dan sama dengan layanan Firebase lainnya, seperti Functions. Untuk codelab ini, Anda dapat mempertahankan region default atau memilih region yang paling dekat dengan Anda.
  4. Klik Enable untuk menyediakan database Firestore Anda.

Mari kita luangkan waktu sejenak untuk mem-build Aturan Keamanan yang andal ke database Firestore. Buka dasbor Firestore, lalu buka tab Aturan. Kemudian, update Aturan Keamanan agar terlihat seperti ini:

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

Aturan ini pada dasarnya mengatakan bahwa setiap pengguna aplikasi yang login dapat membuat dokumen untuk dirinya sendiri dalam koleksi mana pun. Kemudian, setelah dokumen dibuat, hanya pengguna yang membuat dokumen tersebut yang dapat melihat, memperbarui, atau menghapus dokumen tersebut.

Menjalankan aplikasi

Sekarang Anda siap menjalankan aplikasi. Buka folder make-it-so-android/start di Android Studio dan jalankan aplikasi (dapat dilakukan menggunakan Android Emulator atau perangkat Android sungguhan).

3. Firebase Authentication

Fitur mana yang akan Anda tambahkan?

Dalam status aplikasi contoh Make It So saat ini, pengguna dapat mulai menggunakan aplikasi tanpa harus login terlebih dahulu. Sistem ini menggunakan otentikasi anonim untuk melakukannya. Namun, akun anonim tidak memungkinkan pengguna mengakses data mereka di perangkat lain atau bahkan di sesi mendatang. Meskipun autentikasi anonim berguna untuk orientasi yang hangat, Anda harus selalu memberikan opsi bagi pengguna untuk melakukan konversi ke bentuk login lain. Dengan mempertimbangkan hal tersebut, dalam codelab ini, Anda akan menambahkan autentikasi email dan sandi ke aplikasi Make It So.

Saatnya membuat kode!

Segera setelah pengguna membuat akun, dengan mengetik email dan sandi, Anda perlu meminta kredensial email ke Firebase Authentication API, lalu menautkan kredensial baru tersebut ke akun anonim. Buka file AccountServiceImpl.kt di Android Studio dan update fungsi linkAccount sehingga terlihat seperti berikut:

model/service/impl/AccountServiceImpl.kt

override suspend fun linkAccount(email: String, password: String) {
    val credential = EmailAuthProvider.getCredential(email, password)
    auth.currentUser!!.linkWithCredential(credential).await()
}

Sekarang buka SignUpViewModel.kt dan panggil fungsi linkAccount layanan di dalam blok launchCatching fungsi onSignUpClick:

screens/sign_up/SignUpViewModel.kt

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

Pertama, fungsi ini mencoba untuk mengautentikasi, dan jika panggilan berhasil, panggilan berlanjut ke layar berikutnya (SettingsScreen). Saat Anda menjalankan panggilan ini di dalam blok launchCatching, jika terjadi error pada baris pertama, pengecualian akan tertangkap dan ditangani, dan baris kedua tidak akan dijangkau sama sekali.

Segera setelah SettingsScreen dibuka kembali, Anda harus memastikan bahwa opsi Login dan Create account sudah tidak ada, karena sekarang pengguna sudah diautentikasi. Untuk melakukannya, mari kita buat SettingsViewModel memproses status pengguna saat ini (tersedia di AccountService.kt), untuk memeriksa apakah akun tersebut anonim atau tidak. Untuk melakukannya, update uiState di SettingsViewModel.kt agar terlihat seperti berikut:

screens/settings/SettingsViewModel.kt

val uiState = accountService.currentUser.map {
    SettingsUiState(it.isAnonymous)
}

Hal terakhir yang perlu Anda lakukan adalah mengupdate uiState di SettingsScreen.kt untuk mengumpulkan status yang dikeluarkan oleh SettingsViewModel:

screens/settings/SettingsScreen.kt

val uiState by viewModel.uiState.collectAsState(
    initial = SettingsUiState(false)
)

Sekarang, setiap kali pengguna berubah, SettingsScreen akan merekomposisi sendiri untuk menampilkan opsi sesuai dengan status autentikasi baru pengguna.

Saatnya menguji!

Jalankan Make it So dan buka setelan dengan mengklik ikon roda gigi di sudut kanan atas layar. Dari sana, klik opsi buat akun:

Layar pengaturan Jadikan Jadi Layar Daftar Jadi

Ketik email yang valid dan sandi yang kuat untuk membuat akun. Langkah tersebut akan berfungsi dan Anda akan dialihkan ke halaman setelan, tempat Anda akan melihat dua opsi baru: logout dan menghapus akun Anda. Anda bisa memeriksa akun baru yang dibuat pada dasbor Authentication pada Firebase console dengan mengklik tab Users.

4. Cloud Firestore

Fitur mana yang akan Anda tambahkan?

Untuk Cloud Firestore, Anda akan menambahkan pemroses ke koleksi Firestore yang menyimpan dokumen yang mewakili tugas yang ditampilkan di Buat Jadi. Setelah menambahkan pemroses ini, Anda akan menerima setiap pembaruan yang dibuat pada koleksi ini.

Saatnya membuat kode!

Perbarui Flow yang tersedia di StorageServiceImpl.kt agar terlihat seperti ini:

model/layanan/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()
      }

Kode ini menambahkan pemroses ke koleksi tugas berdasarkan user.id. Setiap tugas diwakili oleh dokumen dalam koleksi yang bernama tasks, dan masing-masing memiliki kolom bernama userId. Perhatikan bahwa Flow baru akan ditampilkan jika status currentUser berubah (misalnya dengan logout).

Sekarang Anda harus membuat Flow di TasksViewModel.kt mencerminkan hal yang sama seperti di layanan:

layar/tasks/TasksViewModel.kt

val tasks = storageService.tasks

Hal terakhir adalah membuat composable function di TasksScreens.kt, yang mewakili UI, mengetahui alur ini dan mengumpulkannya sebagai status. Setiap kali status berubah, fungsi composable akan otomatis merekomposisi dan menampilkan status terbaru kepada pengguna. Tambahkan ini ke TasksScreen composable function:

layar/tasks/TasksScreen.kt

val tasks = viewModel
    .tasks
    .collectAsStateWithLifecycle(emptyList())

Setelah fungsi composable memiliki akses ke status ini, Anda dapat mengupdate LazyColumn (yaitu struktur yang Anda gunakan untuk menampilkan daftar di layar) agar terlihat seperti ini:

layar/tasks/TasksScreen.kt

LazyColumn {
    items(tasks.value, key = { it.id }) { taskItem ->
        TaskItem( [...] )
    }
}

Saatnya menguji!

Untuk menguji apakah itu berfungsi, tambahkan tugas baru menggunakan aplikasi (dengan mengklik tombol add di sudut kanan bawah layar). Setelah selesai membuat tugas, tugas tersebut akan muncul di koleksi Firestore di Firestore Console. Jika Anda login Jadikan Jadi di perangkat lain dengan akun yang sama, Anda akan dapat mengedit item daftar tugas dan melihatnya diperbarui di semua perangkat secara real time.

5. Performance Monitoring

Fitur mana yang akan Anda tambahkan?

Performa adalah hal yang sangat penting untuk diperhatikan karena pengguna sangat cenderung akan menyerah menggunakan aplikasi Anda jika performanya tidak baik dan mereka membutuhkan terlalu banyak waktu untuk menyelesaikan tugas sederhana menggunakan aplikasi tersebut. Oleh karena itu, terkadang ada baiknya mengumpulkan beberapa metrik tentang perjalanan tertentu yang dilakukan pengguna di aplikasi Anda. Dan untuk membantu Anda, Firebase Performance Monitoring menawarkan trace kustom. Ikuti langkah berikutnya untuk menambahkan trace kustom dan mengukur performa dalam berbagai kode di Make it So.

Saatnya membuat kode!

Saat membuka file Performance.kt, Anda akan melihat fungsi inline yang disebut rekaman aktivitas. Fungsi ini memanggil Performance Monitoring API untuk membuat trace kustom, yang meneruskan nama trace sebagai parameter. Parameter lain yang Anda lihat adalah blok kode yang ingin Anda pantau. Metrik default yang dikumpulkan untuk setiap trace adalah waktu yang diperlukan untuk berjalan sepenuhnya:

model/service/Performance.kt

inline fun <T> trace(name: String, block: Trace.() -> T): T = Trace.create(name).trace(block)

Anda dapat memilih bagian codebase yang menurut Anda penting untuk diukur dan menambahkan trace kustom ke dalamnya. Berikut adalah contoh penambahan pelacakan kustom ke fungsi linkAccount yang Anda lihat sebelumnya (di AccountServiceImpl.kt) dalam codelab ini:

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()
  }

Sekarang giliran Anda! Tambahkan beberapa rekaman aktivitas kustom ke aplikasi Make it So dan lanjutkan ke bagian berikutnya untuk menguji apakah berfungsi seperti yang diharapkan.

Saatnya menguji!

Setelah selesai menambahkan trace kustom, jalankan aplikasi dan pastikan untuk menggunakan fitur yang ingin Anda ukur beberapa kali. Selanjutnya, buka Firebase console dan buka Dasbor performa. Di bagian bawah layar, Anda akan menemukan tiga tab: Permintaan jaringan, Pelacakan kustom, dan Rendering layar.

Buka tab Custom trace dan pastikan trace yang Anda tambahkan di codebase ditampilkan di sana, dan Anda dapat melihat durasi waktu yang biasanya diperlukan untuk mengeksekusi kode ini.

6. Remote Config

Fitur mana yang akan Anda tambahkan?

Ada banyak kasus penggunaan Remote Config, mulai dari mengubah tampilan aplikasi dari jarak jauh hingga mengonfigurasi perilaku yang berbeda untuk segmen pengguna yang berbeda. Dalam codelab ini, Anda akan menggunakan Remote Config untuk membuat tombol fitur yang akan menampilkan atau menyembunyikan fitur edit task baru di aplikasi Make it So.

Saatnya membuat kode!

Hal pertama yang perlu Anda lakukan adalah membuat konfigurasi di Firebase console. Untuk melakukannya, Anda harus membuka dasbor Remote Config dan mengklik tombol Add parameter. Isi kolom sesuai dengan gambar di bawah ini:

Dialog Create a Parameter Remote Config

Setelah semua kolom terisi, Anda dapat mengklik tombol Simpan, lalu Publikasikan. Setelah parameter dibuat dan tersedia untuk codebase, Anda perlu menambahkan kode yang akan mengambil nilai baru ke aplikasi Anda. Buka file ConfigurationServiceImpl.kt dan update implementasi kedua fungsi ini:

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()

Fungsi pertama mengambil nilai dari server, dan dipanggil segera setelah aplikasi dimulai, di SplashViewModel.kt. Ini adalah cara terbaik untuk memastikan bahwa nilai terbaru akan tersedia di semua layar sejak awal. Ini bukan pengalaman pengguna yang baik jika Anda mengubah UI atau perilaku aplikasi nanti, saat pengguna sedang melakukan sesuatu.

Fungsi kedua menampilkan nilai boolean yang dipublikasikan untuk parameter yang baru saja Anda buat di Konsol. Anda harus mengambil informasi ini di TasksViewModel.kt, dengan menambahkan hal berikut ke fungsi loadTaskOptions:

layar/tasks/TasksViewModel.kt

fun loadTaskOptions() {
  val hasEditOption = configurationService.isShowTaskEditButtonConfig
  options.value = TaskActionOption.getOptions(hasEditOption)
}

Anda mengambil nilai di baris pertama dan menggunakannya untuk memuat opsi menu untuk item tugas di baris kedua. Jika nilainya false, berarti menu tidak akan berisi opsi edit. Sekarang setelah memiliki daftar opsi, Anda harus membuat UI menampilkannya dengan benar. Saat mem-build aplikasi dengan Jetpack Compose, Anda harus mencari composable function yang mendeklarasikan tampilan UI TasksScreen. Jadi, buka file TasksScreen.kt dan perbarui LazyColum agar mengarah ke opsi yang tersedia di TasksViewModel.kt:

layar/tasks/TasksScreen.kt

val options by viewModel.options

LazyColumn {
  items(tasks.value, key = { it.id }) { taskItem ->
    TaskItem(
      options = options,
      [...]
    )
  }
}

TaskItem adalah composable function lain yang mendeklarasikan tampilan UI dari satu tugas. Setiap tugas memiliki menu dengan opsi yang akan ditampilkan saat pengguna mengklik ikon tiga titik di ujungnya.

Saatnya menguji!

Sekarang Anda siap untuk menjalankan aplikasi. Pastikan nilai yang Anda publikasikan menggunakan Firebase console cocok dengan perilaku aplikasi:

  • Jika false, Anda hanya akan melihat dua opsi saat mengklik ikon tiga titik;
  • Jika true, Anda akan melihat tiga opsi saat mengklik ikon tiga titik;

Coba ubah nilai beberapa kali di Konsol, lalu mulai ulang aplikasi. Begitulah mudah untuk meluncurkan fitur baru di aplikasi Anda menggunakan Remote Config.

7. Selamat

Selamat, Anda telah berhasil membangun aplikasi Android dengan Firebase dan Jetpack Compose.

Anda telah menambahkan Firebase Authentication, Performance Monitoring, Remote Config, dan Cloud Firestore ke aplikasi Android yang sepenuhnya dibangun dengan Jetpack Compose untuk UI, dan Anda telah menyesuaikannya dengan arsitektur MVVM yang direkomendasikan.

Bacaan lebih lanjut

Dokumen referensi