Authenticating phone number without sending SMS in Firebase for Android

不羁的心 提交于 2020-05-24 05:06:33

问题


I want to use Firebase phone number authentication. My code is this:

LoginActivity.kt

import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.google.android.gms.tasks.Task
import com.google.firebase.FirebaseException
import com.google.firebase.auth.AuthResult
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.PhoneAuthCredential
import com.google.firebase.auth.PhoneAuthProvider
import kotlinx.android.synthetic.main.login_activity.*
import java.util.concurrent.TimeUnit


class LoginActivity : AppCompatActivity() {
    lateinit var mCallbacks: PhoneAuthProvider.OnVerificationStateChangedCallbacks
    lateinit var mAuth: FirebaseAuth
    var verificationId = ""
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.login_activity)
        mAuth = FirebaseAuth.getInstance()
        veriBtn.setOnClickListener {
            if (phnNoTxt.text.toString()!=""){
            progress.visibility = View.VISIBLE
            verify ()}
                else toast("Enter verification number")
        }
        authBtn.setOnClickListener {
            if ((verifiTxt.text.toString()!="")&&(phnNoTxt.text.toString()!="")){
            progress.visibility = View.VISIBLE
            authenticate()}
            else toast("Enter phone number and its verification number")
        }
    }
    private fun verificationCallbacks () {
        mCallbacks = object: PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
            override fun onVerificationCompleted(credential: PhoneAuthCredential) {
                progress.visibility = View.INVISIBLE
                signIn(credential)
                Log.d("abc","1")
            }
            override fun onVerificationFailed(p0: FirebaseException) {
                progress.visibility=View.GONE
                Log.d("abc","2")}
            override fun onCodeSent(verfication: String, p1: PhoneAuthProvider.ForceResendingToken) {
                super.onCodeSent(verfication, p1)
                verificationId = verfication
                progress.visibility = View.INVISIBLE
                Log.d("abc","3")
            }
        }
    }
    private fun verify () {
        verificationCallbacks()
        val phnNo ="+"+ phnNoTxt.text.toString()

        PhoneAuthProvider.getInstance().verifyPhoneNumber(
            phnNo,
            60,
            TimeUnit.SECONDS,
            this,
            mCallbacks
        )
    }
    private fun signIn (credential: PhoneAuthCredential) {
        mAuth.signInWithCredential(credential)
            .addOnCompleteListener {
                    task: Task<AuthResult> ->
                if (task.isSuccessful) {
                    toast("Sign in Successfully :)")
                }
            }
    }
    private fun authenticate () {

        val verifiNo = verifiTxt.text.toString()

        val credential: PhoneAuthCredential = PhoneAuthProvider.getCredential(verificationId, verifiNo)

        signIn(credential)

    }
    private fun toast (msg: String) {
        Toast.makeText(this, msg, Toast.LENGTH_LONG).show()
    }

}

login_activity.xml

<?xml version="1.0" encoding="utf-8"?>
<ScrollView android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:layout_gravity="center"
    xmlns:android="http://schemas.android.com/apk/res/android">
            <EditText
                android:id="@+id/phnNoTxt"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_alignParentTop="true"
                android:layout_centerHorizontal="true"
                android:hint="Phone Number"
                android:inputType="number"
                android:textAlignment="center"
                android:textSize="24sp"
                android:gravity="center_horizontal" />

            <EditText
                android:id="@+id/verifiTxt"
                android:text=""
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_alignParentStart="true"
                android:textAlignment="center"
                android:inputType="number"
                android:layout_below="@+id/phnNoTxt"
                android:hint="Verification Code"
                android:gravity="center_horizontal"
                android:layout_alignParentLeft="true" />
            <ProgressBar
                android:id="@+id/progress"
                style="?android:attr/progressBarStyle"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:visibility="gone" />

            <Button
                android:id="@+id/veriBtn"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@+id/verifiTxt"
                android:layout_centerHorizontal="true"
                android:layout_gravity="center"
                android:text="Verify" />

            <Button
                android:id="@+id/authBtn"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@+id/veriBtn"
                android:layout_centerHorizontal="true"
                android:layout_gravity="center"
                android:text="Authenticate" />
        </LinearLayout>
</ScrollView>

When I enter my phone number for first time, Firebase sends me SMS, in fact in verificationCallbacks (), the third one will run (onCodeSent). After that when I enter again my phone number, in verificationCallbacks (), the first one will run (onVerificationCompleted). It's rational. But it is strange for me that after I deleted SMS verification code from my phone and deleted my phone number from Firebase, although I expected Firebase to send me SMS and (onCodeSent) run, but again (onVerificationCompleted) ran. When I test in another phone, it worked as I like. Every time I entered my phone number (in another phone not the phone my simcard is in it), Firebase sent me SMS with code and it authenticated my phone number if the code was correct. I want Firebase to send me SMS everytime I enter my phone number, either I try it in the phone my simcard is in it or in another phone. Is it possible? How should I change my code?


回答1:


There seems no way to do that without an SMS. Even in firebase docs it's mentioned it will be done through SMS by sending a code. And how would you verify code without SMS? The phone number is not a property of your android device. It's somewhere with your operator. Even if you manage to get a phone number in a string and create your own way to verify the phone number it won't be safe and can be misused by reverser-engineering.

This is mentioned in the docs.

onCodeAutoRetrievalTimeOut(String verificationId) Optional. This method is called after the timeout duration specified to verifyPhoneNumber has passed without onVerificationCompleted triggering first. On devices without SIM cards, this method is called immediately because SMS auto-retrieval isn't possible.

Now coming back to the topic, this is possible but during testing. You can whitelist the numbers and the OTP or code via SMS won't be sent. However there are some conditions for it. https://firebase.google.com/docs/auth/android/phone-auth#test-with-whitelisted-phone-numbers

Secondly, you seem to have an issue where you delete the phone number but firebase still ran onVerificationCmoplete. Try deleting the user from the Authentication tab and refreshing it. And if your code keeps trace of the phone number or user data afiiliated with that number, make sure you clean that as well.



来源:https://stackoverflow.com/questions/61038436/authenticating-phone-number-without-sending-sms-in-firebase-for-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!