Membangun 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 membangun aplikasi Android bernama Make It So. UI aplikasi ini sepenuhnya dibangun dengan Jetpack Compose, yang merupakan toolkit modern Android untuk membangun UI native - bersifat intuitif dan membutuhkan lebih sedikit kode daripada menulis file .xml dan mengikatnya ke Aktivitas, Fragmen, atau Tampilan.

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 dipelihara, karena membuat sistem menjadi sangat jelas bagaimana komponen diatur dan berkomunikasi satu sama lain. Di dunia Android, arsitektur yang direkomendasikan disebut Model - Tampilan - ViewModel. Model merepresentasikan lapisan yang mengakses Data dalam aplikasi. View adalah lapisan UI dan seharusnya tidak mengetahui apa pun tentang logika bisnis. Selain itu, ViewModel adalah tempat logika bisnis diterapkan, yang terkadang memerlukan ViewModel untuk memanggil lapisan Model.

Sebaiknya baca artikel ini untuk memahami cara penerapan Model - Tampilan - ViewModel ke aplikasi Android yang dibuat dengan Jetpack Compose karena akan membuat codebase lebih mudah dipahami dan langkah selanjutnya 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 ini menampilkan dua halaman utama aplikasi ini: halaman pembuatan tugas dan halaman utama yang berisi daftar tugas yang dibuat.

Layar Buat Jadi Tambahkan Tugas 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 di 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

Buat clone repositori GitHub dari command line:

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

Menyiapkan Firebase

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

Firebase console

Ikuti langkah-langkah di layar untuk menyelesaikan pembuatan proyek.

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 dan mengakses file konfigurasi Firebase.
  3. Klik Download google-services.json untuk mendownload file konfigurasi dan menyimpannya di direktori make-it-so-android/app.
  4. Klik Next. Karena Firebase SDK sudah disertakan dalam file build.gradle di project contoh, klik Next untuk 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 Console sebelum beralih ke kode: mengaktifkan penyedia autentikasi dan membuat database Firestore. Pertama, mari kita aktifkan Authentication sehingga 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. Selanjutnya, 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 tempat data Cloud Firestore Anda akan disimpan. Saat mengembangkan aplikasi produksi, Anda perlu berada di region yang dekat dengan sebagian besar pengguna Anda 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 luangkan waktu sejenak untuk membangun Aturan Keamanan yang andal pada database Firestore. Buka dasbor Firestore dan buka tab Rules. Kemudian, perbarui 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 menyatakan bahwa setiap pengguna aplikasi yang login dapat membuat dokumen untuk dirinya sendiri dalam koleksi apa pun. Kemudian, setelah dibuat, hanya pengguna yang membuat dokumen tersebut yang dapat melihat, memperbarui, atau menghapus dokumen tersebut.

Menjalankan aplikasi

Sekarang Anda siap untuk 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. Untuk melakukannya, menggunakan otentikasi anonim. Namun, akun anonim tidak mengizinkan pengguna mengakses datanya di perangkat lain atau bahkan di sesi yang akan datang. Meskipun autentikasi anonim berguna untuk orientasi yang hangat, Anda harus selalu memberikan opsi bagi pengguna untuk melakukan konversi ke bentuk login yang berbeda. Dengan mempertimbangkan hal ini, 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 tersebut. 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 dari fungsi onSignUpClick:

screens/sign_up/SignUpViewModel.kt

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

Pertama, aplikasi mencoba mengautentikasi, dan jika berhasil, panggilan dilanjutkan ke layar berikutnya (SettingsScreen). Saat Anda menjalankan panggilan ini di dalam blok launchCatching, jika terjadi error di baris pertama, pengecualian akan ditangkap dan ditangani, dan baris kedua tidak akan tercapai sama sekali.

Segera setelah SettingsScreen dibuka kembali, Anda perlu memastikan bahwa opsi untuk Login dan Buat akun tidak ada lagi, karena pengguna sekarang 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 dimunculkan 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 pojok kanan atas layar. Dari sana, klik opsi buat akun:

Layar setelan Buatlah Jadi Layar pendaftaran Make it So

Ketik email yang valid dan sandi yang kuat untuk membuat akun. Cara ini akan berhasil dan Anda akan dialihkan ke halaman setelan, tempat Anda akan melihat dua opsi baru: logout dan menghapus akun. Anda dapat memeriksa akun baru yang dibuat di 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 merepresentasikan tugas yang ditampilkan di Make it So. 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/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()
      }

Kode ini menambahkan pemroses ke kumpulan tugas berdasarkan user.id. Setiap tugas direpresentasikan oleh dokumen dalam koleksi bernama tasks, dan setiap tugas memiliki kolom bernama userId. Perlu diketahui bahwa Flow baru akan dimunculkan jika status currentUser berubah (misalnya, dengan logout).

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

screens/tasks/TasksViewModel.kt

val tasks = storageService.tasks

Dan 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 sendiri dan menampilkan status terbaru kepada pengguna. Tambahkan ini ke TasksScreen composable function:

screens/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:

screens/tasks/TasksScreen.kt

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

Saatnya menguji!

Untuk menguji apakah itu berhasil, tambahkan tugas baru menggunakan aplikasi (dengan mengeklik tombol tambahkan di sudut kanan bawah layar). Setelah selesai dibuat, tugas akan muncul di koleksi Firestore di Firestore Console. Jika login ke Make it So 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 mungkin untuk berhenti menggunakan aplikasi Anda jika performanya tidak baik dan mereka menghabiskan terlalu banyak waktu untuk menyelesaikan tugas sederhana menggunakannya. Oleh karena itu, terkadang ada baiknya untuk mengumpulkan beberapa metrik tentang perjalanan tertentu yang dilakukan pengguna di aplikasi Anda. Firebase Performance Monitoring menawarkan pelacakan kustom untuk membantu Anda. Ikuti langkah-langkah berikutnya untuk menambahkan trace kustom dan mengukur performa di berbagai bagian kode di Make it So.

Saatnya membuat kode.

Saat membuka file Performance.kt, Anda akan melihat fungsi inline yang disebut trace. Fungsi ini memanggil Performance Monitoring API untuk membuat pelacakan kustom, dengan meneruskan nama pelacakan 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. Berikut adalah contoh penambahan rekaman aktivitas kustom ke fungsi linkAccount yang telah 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 Performance. Di bagian bawah layar, Anda akan menemukan tiga tab: Permintaan jaringan, Trace kustom, dan Rendering layar.

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

6. Remote Config

Fitur mana yang akan Anda tambahkan?

Ada banyak kasus penggunaan untuk Remote Config, mulai dari mengubah tampilan aplikasi Anda 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 tugas edit 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 Save, lalu Publish. Setelah parameter dibuat dan tersedia untuk codebase, Anda harus menambahkan kode yang akan mengambil nilai baru ke aplikasi. 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, dalam SplashViewModel.kt. Ini adalah cara terbaik untuk memastikan bahwa nilai terbaru akan tersedia di semua layar sejak awal. Ini bukanlah pengalaman pengguna yang baik jika Anda mengubah UI atau perilaku aplikasi nanti, saat pengguna sedang melakukan sesuatu.

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

screens/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, artinya menu tidak akan berisi opsi edit. 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:

screens/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. Dan setiap tugas memiliki menu dengan opsi yang ditampilkan saat pengguna mengklik ikon tiga titik di ujungnya.

Saatnya menguji!

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

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

Coba ubah nilai beberapa kali di Konsol dan mulai ulang aplikasi. Begitulah mudahnya meluncurkan fitur baru di aplikasi Anda menggunakan Remote Config.

7. Selamat

Selamat, Anda 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 membuatnya sesuai dengan arsitektur MVVM yang direkomendasikan.

Bacaan lebih lanjut

Dokumen referensi