4

I'm trying to add the Firebase Phone Authentication code inside a View Model using Kotlin. The problem is that the PhoneAuthProvider requires an activity. Does anyone know how can this code be implemented inside a View Model without the need of an activity?

Thanks!

val mCallbacks: PhoneAuthProvider.OnVerificationStateChangedCallbacks ...

val options = PhoneAuthOptions.newBuilder(auth).apply {
  setPhoneNumber(phoneNumber)
  setTimeout(120L, TimeUnit.SECONDS)
  setActivity(this) <-------------------------- // Activity (for callback binding)
  setCallbacks(mCallbacks)
}.build()
PhoneAuthProvider.verifyPhoneNumber(options)
Toufic Batache
  • 762
  • 10
  • 24

2 Answers2

2

It turned out to be an intentional change in API 20 (check out this issue on Github), even though it violates the MVVM architecture. The reason an activity is needed is that the method falls back to reCAPTCHA. The right way to achieve it is "yet to be determined".

Toufic Batache
  • 762
  • 10
  • 24
1

My approach is to include everything in the viewModel including the callbacks. I then call a function in the viewModel and pass in an activity parameter. see below:

fun verifyPhoneNumber(phoneNumber: String, activity: Activity) {
        _validFullPhoneNumber.value = phoneNumber
        val options = PhoneAuthOptions.newBuilder(mAuth)
            .setPhoneNumber(phoneNumber)       // Phone number to verify
            .setTimeout(60L, TimeUnit.SECONDS) // Timeout and unit
            .setActivity(activity)
            .setCallbacks(callbacks)          // OnVerificationStateChangedCallbacks
            .build()
        PhoneAuthProvider.verifyPhoneNumber(options)
    }

and in the UI controller, in my case a fragment I call it as:

viewModel.verifyPhoneNumber(validatedPhoneNumber, requireActivity())

same with resend button function.

viewModel:

fun resendVerificationCode(activity: Activity) {
        val options =
            PhoneAuthOptions.newBuilder(mAuth)
                .setPhoneNumber(_validFullPhoneNumber.value!!) // Phone number to verify
                .setTimeout(60L, TimeUnit.SECONDS) // Timeout and unit
                .setActivity(activity)
                .setCallbacks(callbacks) // OnVerificationStateChangedCallbacks
                .setForceResendingToken(_resendToken) // ForceResendingToken from callbacks
                .build()

        PhoneAuthProvider.verifyPhoneNumber(options)
        _isVerificationCodeExpired.value = false
    }

UI controller(fragment):

 viewModel.resendVerificationCode(requireActivity())
thinclient
  • 1,361
  • 2
  • 5
  • 6