android - 通过电话验证 Firebase 不起作用
问题描述
使用 Firebase,我试图通过电话号码获取 SMS 代码,但它不起作用。在两种情况下一切都不起作用:
onVerificationCompleted()
带有日志消息的内部函数sms code is null
。- 访问
startPhoneNumberVerification()
功能日志后停止写入,我也没有收到短信代码。
我阅读了文档,查看了 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 代码发送到其他号码。
我将不胜感激任何答案。
解决方案
您首先需要在 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>
我实际上使用的是我从另一个人那里得到的电话号码,但你绝对可以改变这个,希望它有帮助
推荐阅读
- c++ - C++ 多线程循环
- javascript - javascript 检查字符串和启动模式的链接
- java - 使用 Jersey 将 pojo 解析为 Json
- java - 使用时区解析日期并保留时区值
- javascript - AngularJS 自定义表单验证
- vb.net - 尝试无限引用方形图片框碰撞
- magento - 将 magento 1.9.3 迁移到 prestashop 1.16.1.18
- google-places-api - Google Places API 搜索不一致
- php - 使用属性解析 Json 响应
- reactjs - 在 React 的函数中调用事件处理程序