📱
Integrasi Flutter dengan Firebase Phone Auth

Referensi Install Flutter:

FlutterFire documentation

Firebase documentation

Referensi Phone Auth ke Firebase:

Tutorial Resmi Dari Firebase

Dokumentasi Resmi FlutterFire

Dokumentasi Resmi dari Firebase

API Limits

Autentikasi Client (SHA-1 and SHA-256 signing)

App Signing for Production

Tutorial video seluruh tahapan dari awal hingga akhir (2021)

Dokumentasi implementasi Firebase Phone Auth

Alur

Alur dari Firebase Phone Auth secara normalnya adalah:

▶️
verifikasi nomor telpon → signIn (menggunakan OTP) → berhasil mendapatkan UserCredential

Persiapan Development

  1. Enable Authentication menggunakan Phone pada Firebase.
  1. Enable Android Device Verification API pada google console. Pastikan akun dan project yang digunakan sesuai dengan yang dipakai Firebase.
  1. Masukkan SHA-1 dan SHA-256 Fingerprint setiap developer untuk melakukan self-signing aplikasi. Tahap ini akan dibahas lebih lanjut di bagian selanjutnya.
  1. Download google-services.json dan masukkan dalam folder android/app
  1. Tambahkan dependencies yang sesuai. Perlu diperhatikan bahwa harus terdapat dependensi tambahan juga yaitu implementation "androidx.browser:browser:1.3.0". Hal ini dijelaskan lebih lanjut pada bagian App Verification.
  1. Lakukan implementasi.

Self-Signing dengan SHA-1 dan SHA-256

Terdapat 2 cara untuk mendapatkan SHA-1 dan SHA-256, yaitu dengan menggunakan gradle atau dengan menggunakan keytool (dari JDK/JRE). Pada Windows, dapat digunakan perintah berikut pada command line:

keytool -list -v -alias androiddebugkey -keystore "%USERPROFILE%\.android\debug.keystore" --storepass android --keypass android

Atau bisa juga menggunakan gradle dengan perintah berikut (pastikan sudah berada dalam direktori android pada project:

./gradlew signingReport

Perlu diperhatikan bahwa self-signing seperti ini hanya berlaku untuk 1 device (atau 1 build) sehingga setiap developer harus memasukkan SHA Fingerprint mereka ke dalam Firebase. Apabila sudah mencapai tahap production, seharusnya dapat menggunakan Play App Signing yang dapat dilihat lebih lanjut pada referensi di atas.

App Verification

Firebase menggunakan 2 metode untuk melakukan verifikasi aplikasi, yaitu dengan SafetyNet dan reCAPTCHA. Berikut adalah penjelasan dari Firebase.

Notion image

Secara garis besar, SafetyNet adalah cara verifikasi otomatis yang berjalan langsung ditempat sementara reCAPTCHA adalah cara verifikasi melalui browser yang mengarah pada firebaseapp. Apabila verifikasi menggunakan SafetyNet gagal, maka Firebase akan fallback dengan verifikasi menggunakan reCAPTCHA sehingga harus ditambahkan implementation "androidx.browser:browser:1.3.0" pada dependency agar tidak terjadi crash.

Sayangnya, masih terdapat ketidakjelasan mengenai kapan SafetyNet terjadi kegagalan. Berdasarkan StackOverflow ini beserta dokumentasi Firebase, terdapat 5 kondisi yang dapat membuat SafetyNet gagal:

  1. Android Device Verification API tidak di-enable pada Google Cloud Console.
  1. SHA-256 Fingerprint tidak dimasukkan ke dalam Firebase (atau lupa meng-update google-services.json).
  1. Perangkat tidak memiliki dukungan Google Play Services.
  1. Pengetesan dilakukan pada emulator.
  1. Perangkat telah dilakukan rooting atau bootloader-nya dalam kondisi unlocked.

Beberapa error di atas tidak akan fallback ke reCAPTCHA (misalnya error no. 2 akan langsung mengembalikan authentication failure atau missing client identifier). Tidak perlu takut apabila pada suatu device dilakukan verifikasi aplikasi menggunakan browser karena bisa jadi device tersebut telah di-root atau di-unlock bootloader-nya.

Verifikasi Nomor Telpon

Verifikasi nomor telpon pada Firebase dilakukan dengan memakai fungsi verifyPhoneNumber. Fungsi ini harus dipanggil dengan memberikan minimal 5 parameter berikut:

String phoneNumber: nomor HP yang ingin diverifikasi.

phoneNumber harus memakai format dengan awalan "+" (misal: +62812...) sehingga nomor yang berawalan "0" (misal: 0812...) harus diubah menjadi "+62".

Function(PhoneAuthCredential) verificationCompleted: callback yang dipanggil ketika verifikasi secara otomatis berhasil dilaksanakan.

Callback ini menerima PhoneAuthCredential yang isinya dapat dipakai untuk melakukan signInWithPhoneAuthCredential (signIn menggunakan nomor HP). Dari PhoneAuthCredential juga dapat diketahui smsCode yang diterima secara otomatis.

Function(FirebaseAuthException) verificationFailed: callback yang dipanggil ketika verifikasi secara otomatis gagal .

Callback ini menerima FirebaseAuthException (inherit dari FirebaseException) yang dapat dipakai untuk mengetahui alasan kegagalan.

Function(String, int) codeSent: callback yang dipanggil ketika request verifikasi berhasil dilaksanakan.

Callback ini menerima String verificationId dan int forceResendingToken dimana verificationId dibutukan untuk melakukan signInWithPhoneAuthCredential dan forceResendingToken dibutuhkan untuk melakukan request ulang verifikasi (atau dalam kata lain: resend OTP).

Function(String) codeAutoRetrievalTimeout: callback yang dipanggil ketika verifikasi secara otomatis gagal dilaksanakan akibat timeout.

Callback ini menerima String verificationId yang sama dengan yang terdapat pada parameter codeSent. Callback ini akan dipanggil otomatis tanpa menunggu timeout apabila verifikasi dilakukan dalam emulator. Sebenarnya tidak terlalu berguna, namun mungkin bisa dimanfaatkan untuk memberitahu pengguna apabila FirebaseAuth tidak dapat mendeteksi smsCode.

Terdapat juga parameter opsional yang cukup penting, seperti:

  • Duration timeout: lama FirebaseAuth akan mendeteksi smsCode. Default-nya 30 detik.
  • int forceResendingToken: token yang digunakan untuk melakukan request ulang verifikasi.

Perlu diperhatikan bahwa apabila menggunakan implementasi verifyPhoneNumber pada Auth service ini, signInWithPhoneAuthCredential dilakukan secara otomatis di verificationCompleted sehingga tidak perlu melakukan signIn lagi. Terdapat juga ValueNotifier<String> smsCode yang dapat digunakan untuk mengecek smsCode yang didapat secara otomatis, yang akan menghapus dirinya sendiri setiap request verifikasi dilakukan.

Verifikasi OTP

Verifikasi OTP dapat dilakukan dengan membuat PhoneAuthCredential dari verificationId serta smsCode lalu melakukan signInWithPhoneAuthCredential. Dalam implementasi Auth service, hal ini dilakukan pada fungsi verifyOtp.

Resend OTP

Resend OTP dapat dilakukan dengan menggunakan verifyPhoneNumber. Caranya adalah dengan menjalankan ulang verifyPhoneNumber tapi dengan ditambahkan parameter forceResendingToken yang sesuai. Apabila forceResendingToken tidak sesuai atau tidak ada dan sedang ada request verifikasi yang berlangsung, maka request yang baru tidak akan dianggap.

Sign In

Sign In dapat dilakukan dengan menggunakan signInWithCredential(AuthCredential) dengan jenis credential disesuaikan dengan tipe autensikasi yang digunakan. Dalam hal ini, credential yang dipakai adalah PhoneAuthCredential sehingga dibuat implementasi fungsi signInWithPhoneAuthCredential untuk melakukan sign in.

Notes

  • Firebase Auth memiliki mekanisme anti-spam (bisa dilihat pada tutorial resmi) yang dapat memblokir suatu IP apabila terlalu banyak request dalam satu waktu. Pada Phone Auth, hal ini dapat terjadi apabila request verifyPhoneNumber melebihi sekitar 5 request dalam 30 menit. Pemblokiran akan berlangsung hingga 4 jam. Namun, hal ini tidak berlaku pada nomor testing.
  • Disarankan nomor testing yang digunakan adalah nomor yang tidak ada (dijelaskan pada tutorial resmi).