首页 > 解决方案 > 通过电话验证 Firebase 不起作用

问题描述

使用 Firebase,我试图通过电话号码获取 SMS 代码,但它不起作用。在两种情况下一切都不起作用:

我阅读了文档,查看了 Github 上不同版本的代码,但我不明白为什么我的代码不起作用。

验证片段

class VerificationFragment : BaseFragment() {

    private lateinit var phone: String

    override val menuResId: Nothing? = null
    override val contentResId = R.layout.fragment_verification
    override val baseToolbar = R.id.toolbar

    private var verificationId = ""

    private val callbacks = object : PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
        override fun onCodeSent(s: String, p1: PhoneAuthProvider.ForceResendingToken) {
            super.onCodeSent(s, p1)
            verificationId = s
        }

        override fun onVerificationCompleted(phoneAuthCredential: PhoneAuthCredential) {
            val code = phoneAuthCredential.smsCode
            if (code != null) {
                Log.d("SmsCode", "onVerificationCompleted(): ща будем верифаить")
                verifyCode(code)
            } else {
                Log.d("SmsCode", "onVerificationCompleted(): sms code is null")
            }
        }

        override fun onVerificationFailed(e: FirebaseException) {
            if (e is FirebaseAuthInvalidCredentialsException) {
                Log.d("SmsCode", "onVerificationFailed(): Invalid request")
            } else if (e is FirebaseTooManyRequestsException) {
                Log.d("SmsCode", "onVerificationFailed(): The SMS quota for the project has been exceeded")
            }
        }

    }

    private fun startPhoneNumberVerification(phoneNumber: String) {
        Log.d("SmsCode", "startPhoneNumberVerification() visited")
        PhoneAuthProvider.getInstance().verifyPhoneNumber(
            phoneNumber,
            60,
            TimeUnit.SECONDS,
            baseActivity,
            callbacks
        )
    }

    fun verifyCode(code: String) {
        Log.d("SmsCode", "verificationId: $verificationId")
        val credential = PhoneAuthProvider.getCredential(verificationId, code)
        singInWithCredential(credential)
    }

    private fun singInWithCredential(credential: PhoneAuthCredential) {
        val mAuth = FirebaseAuth.getInstance()
        mAuth.signInWithCredential(credential)
            .addOnCompleteListener(baseActivity) { task ->
                if (task.isSuccessful) {
                    val fUser = task.result?.user
                    Log.d("SmsCode", "singInWithCredential(): fUser is $fUser")
                } else {
                    Log.d("SmsCode", "singInWithCredential(): error")
                }
            }
    }

    override fun setViews() {
        phone = VerificationFragmentArgs.fromBundle(requireArguments()).phone
        setPhoneNumber()
        startPhoneNumberVerification(phone)
    }

    private fun setPhoneNumber() {
        verificationText.text = String.format(verificationText.text.toString(), phone)
    }
}

基本片段

abstract class BaseFragment: Fragment() {

    val baseActivity: MainActivity
        get() = activity as MainActivity

    private var currentView: View? = null

    protected abstract val menuResId: Int?
    protected abstract val contentResId: Int
    protected abstract val baseToolbar: Int

    protected inline fun <T> LiveData<T>.observe(crossinline codeBlock: (T) -> Unit) {
        observe(this@BaseFragment, Observer { it -> it?.let { codeBlock(it) } })
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
        if (currentView == null) {
            currentView = inflater.inflate(contentResId, container, false)
        }
        return currentView!!
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        setViews()
        setToolbar(view)
        setObservers()
        setListeners()
        setActions()
    }

    protected open fun setViews() {}

    protected open fun setObservers() {}

    protected open fun setListeners() {}

    protected open fun setActions() {}

    fun showBottomBar() = baseActivity.showBottomBar()

    fun hideBottomBar() = baseActivity.hideBottomBar()

    protected open fun setToolbar(view: View) {
        menuResId?.let {
            view.findViewById<MaterialToolbar>(baseToolbar).inflateMenu(it)
        }
    }
}

日志中不会出现足够的 Firebase 消息。我有一个测试号码,但我也无法将 SMS 代码发送到其他号码。

我将不胜感激任何答案。

标签: androidfirebase-authentication

解决方案


您首先需要在 Firebase 中启用电话身份验证,然后您可以按照以下代码进行操作:

public class VerifyPhoneNumActivity extends AppCompatActivity {

protected PinView editTextCode;
protected TextView resendCode;


DatabaseReference reference;

FirebaseUser firebaseUser;

String phone_number;

String code;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    super.setContentView(R.layout.activity_verify_phone_num);
    initView();


    firebaseUser = FirebaseAuth.getInstance().getCurrentUser();

    Intent intent = getIntent();

    phone_number = intent.getStringExtra("phone_number");

    sendVerificationCode(phone_number);


    resendCode.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {


            sendVerificationCode(phone_number);


        }
    });




}


private void sendVerificationCode(String mobile) {
    PhoneAuthProvider.getInstance().verifyPhoneNumber(
            "+20" + mobile,
            60,
            TimeUnit.SECONDS,
            TaskExecutors.MAIN_THREAD,
            mCallbacks);
}


private PhoneAuthProvider.OnVerificationStateChangedCallbacks mCallbacks
        = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
    @Override
    public void onVerificationCompleted(PhoneAuthCredential phoneAuthCredential) {
        //Getting the code sent by SMS
        code = phoneAuthCredential.getSmsCode();

        //sometime the code is not detected automatically
        //in this case the code will be null
        //so user has to manually enter the code
        if (code != null) {
            editTextCode.setText(code);
            //verifying the code
            verifyVerificationCode(code);
        }
    }






    @Override
    public void onVerificationFailed(FirebaseException e) {


        //  public void onVerificationFailed(FirebaseException e) {
       // Toast.makeText(VerifyPhoneNumActivity.this, e.getMessage(), Toast.LENGTH_LONG).show();

        Toast.makeText(VerifyPhoneNumActivity.this, e.getMessage(), Toast.LENGTH_LONG).show();


        reference = FirebaseDatabase.getInstance().getReference("Users").child(firebaseUser.getUid());

        reference.removeValue();

        Intent intent = new Intent();

        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

        finish();

    }


};


private void verifyVerificationCode(String otp) {


    //signing the user


    reference = FirebaseDatabase.getInstance().getReference("Users").child(firebaseUser.getUid());


    HashMap<String, Object> map = new HashMap<>();

    map.put("phone", phone_number);

    reference.updateChildren(map);


    Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            Intent intent = new Intent(VerifyPhoneNumActivity.this, HomeActivity.class);
            startActivity(intent);
            finish();
        }
    }, 5000);


}


private void initView() {
    editTextCode = (PinView) findViewById(R.id.editTextCode);
    resendCode = (TextView) findViewById(R.id.resend_code);

}

}

和 xml 文件:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".controller.Register_Login.VerifyPhoneNumActivity">

<LinearLayout
    android:orientation="vertical"

    android:gravity="center"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:ignore="MissingConstraints">


<com.chaos.view.PinView
    android:id="@+id/editTextCode"
    style="@style/PinWidget.PinView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:inputType="number"
    android:padding="10dp"
    android:layout_marginTop="80dp"
    android:textColor="#222222"
    android:textSize="18sp"
    android:cursorVisible="true"
    app:cursorColor="@color/colorAccent"
    app:cursorWidth="2dp"
    app:itemCount="6"
    app:itemHeight="48dp"
    app:itemRadius="4dp"
    app:itemSpacing="5dp"
    app:itemWidth="36dp"
    app:lineColor="@color/colorPrimary"
    app:lineWidth="2dp"
    app:viewType="rectangle" />


<TextView
    android:id="@+id/resend_code"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textColor="#019b77"
    android:textStyle="bold"
    android:textAlignment="center"
    android:text="@string/i_didn_t_get_a_code"
    android:textSize="20sp"
    android:layout_marginTop="20dp"/>



</LinearLayout>

我实际上使用的是我从另一个人那里得到的电话号码,但你绝对可以改变这个,希望它有帮助


推荐阅读