【问题标题】:Authenticating phone number without sending SMS in Firebase for Android在 Firebase for Android 中验证电话号码而不发送短信
【发布时间】:2020-04-05 05:27:03
【问题描述】:

我想使用 Firebase 电话号码身份验证。我的代码是这样的:

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>

当我第一次输入我的电话号码时,Firebase 会向我发送短信,实际上是在verificationCallbacks (),第三个将运行 (onCodeSent)。之后,当我再次输入我的电话号码时,verificationCallbacks (),第一个将运行 (onVerificationCompleted)。这是理性的。但奇怪的是,在我从手机中删除短信验证码并从 Firebase 中删除我的电话号码后,虽然我希望 Firebase 向我发送短信并 (onCodeSent) 运行,但再次 (onVerificationCompleted) 运行。当我在另一部手机上进行测试时,它可以按我喜欢的方式工作。每次我输入我的电话号码(在另一部电话而不是我的 SIM 卡所在的电话中)时,Firebase 都会向我发送带有代码的短信,如果代码正确,它会验证我的电话号码。我希望 Firebase 每次输入我的电话号码时都会向我发送短信,我可以在我的 SIM 卡在其中的手机中尝试,也可以在另一部手机中尝试。是否可以?我应该如何更改我的代码?

【问题讨论】:

    标签: android kotlin firebase-authentication one-time-password


    【解决方案1】:

    没有短信似乎没有办法做到这一点。即使在firebase docs中也提到它将通过SMS通过发送代码来完成。 如果没有短信,您将如何验证代码?电话号码不是您的 android 设备的属性。它在您的操作员的某个地方。 即使您设法获取字符串中的电话号码并创建自己的方式来验证电话号码,它也不安全,并且可能被逆向工程滥用。

    这在文档中有所提及。

    onCodeAutoRetrievalTimeOut(String verificationId) 可选。这 在指定的超时持续时间后调用方法 verifyPhoneNumber 已通过但没有 onVerificationCompleted 先触发。在没有 SIM 卡的设备上,此方法称为 立即,因为 SMS 自动检索是不可能的。

    现在回到主题,这是可能的,但在测试期间。 您可以将号码列入白名单,并且不会通过短信发送 OTP 或代码。 但是,它有一些条件。 https://firebase.google.com/docs/auth/android/phone-auth#test-with-whitelisted-phone-numbers

    其次,您似乎有一个问题,您删除了电话号码,但 firebase 仍然运行 onVerificationCmoplete。尝试从身份验证选项卡中删除用户并刷新它。如果您的代码跟踪电话号码或与该号码关联的用户数据,请确保您也将其清理干净。

    【讨论】:

    • @MohammadMoeinGolchin 您可以尝试在 authBtn onClickListener 周围添加 if-else 语句吗?尝试检查电话号码是否已被使用。如果它正在使用中,请不要继续,也不要调用函数 authenticate();
    • 我的问题是为什么当我尝试在手机 SIM 卡中没有再次发送短信。也许通过您的解决方案,我摆脱了这个问题,但我的问题没有得到解答。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-01
    • 2012-10-10
    • 2019-08-23
    • 1970-01-01
    相关资源
    最近更新 更多