通过电话进行身份验证Firebase无法正常工作

时间:2020-04-02 19:15:57

标签: android firebase-authentication

我正在尝试使用Firebase通过电话号码获取SMS代码,但该方法无效。在两种情况下,一切都不起作用:

  • 内部onVerificationCompleted()函数和日志消息sms code is null
  • 访问startPhoneNumberVerification()函数日志后停止写操作,我也没有收到短信代码。

我阅读了文档,查看了Github上不同版本的代码,但我不明白为什么我的代码无法正常工作。

VerificationFragment

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)
    }
}

BaseFragment

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代码传送到其他号码。

如果有任何答复,我将不胜感激。

1 个答案:

答案 0 :(得分:0)

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

__attribute__((used))

}

和xml文件:

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);

}

我实际上使用的是我从另一个电话获得的电话号码,但是绝对可以更改它,希望对您有所帮助