[英]Using Firebase phone authentication inside Fragment android
I am making an android app where the only user sign in and register method is via phone authentication.我正在制作一个 android 应用程序,其中唯一的用户登录和注册方法是通过电话身份验证。 I'm having a single activity and making use of fragments.我正在进行一项活动并使用片段。
I want to add firebase phone authentication inside the SignInFragment and make use of Firebase PhoneAuthProvider.However, this is only for activities I suppose, because I tried implementing inside my fragment and my app was crashing.我想在 SignInFragment 中添加 firebase 电话身份验证并使用 Firebase PhoneAuthProvider。但是,这仅适用于我认为的活动,因为我尝试在我的片段中实现并且我的应用程序崩溃了。
This is the code of SignInFragment.java这是 SignInFragment.java 的代码
package com.example.XX;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import com.google.android.gms.tasks.OnCompleteListener;
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.FirebaseAuthInvalidCredentialsException;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.auth.PhoneAuthCredential;
import com.google.firebase.auth.PhoneAuthProvider;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
public class SignInFragment extends Fragment {
private static final String TAG ="INSIDE_SIGN_IN_FRAGMENT" ;
FirebaseAuth mAuth;
EditText xPhone;
EditText xOTP;
String codeSent;
public SignInFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_sign_in, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Button getOTP=view.findViewById(R.id.button_xOTP);
Button submitButton=view.findViewById(R.id.signInbutton);
xPhone=view.findViewById(R.id.editText_xMobile);
xOTP=view.findViewById(R.id.editText_xOTP);
mAuth=FirebaseAuth.getInstance();
getOTP.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
sendVerificationCode();
}
});
submitButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
verifyOTP();
}
});
}
private void verifyOTP(){
String tOTP=xOTP.getText().toString().trim();
if(tOTP.isEmpty()){
xOTP.setError("OTP is required!");
xOTP.requestFocus();
return;
}
if(tOTP.length()<6){
xOTP.setError("Please enter a valid OTP!");
xOTP.requestFocus();
return;
}
PhoneAuthCredential credential = PhoneAuthProvider.getCredential(codeSent, tOTP);
signInWithPhoneAuthCredential(credential);
}
private void signInWithPhoneAuthCredential(PhoneAuthCredential credential) {
mAuth.signInWithCredential(credential)
.addOnCompleteListener((Executor) this, new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
// Sign in success, update UI with the signed-in user's information
Log.d(TAG, "signInWithCredential:success");
FirebaseUser user = task.getResult().getUser();
// ...
} else {
// Sign in failed, display a message and update the UI
Log.w(TAG, "signInWithCredential:failure", task.getException());
if (task.getException() instanceof FirebaseAuthInvalidCredentialsException) {
// The verification code entered was invalid
}
}
}
});
}
private void sendVerificationCode() {
String xMobileNumber=xPhone.getText().toString().trim();
if(xMobileNumber.isEmpty()){
xPhone.setError("Phone number is required!");
xPhone.requestFocus();
return;
}
if(xMobileNumber.length()<10){
xPhone.setError("Please enter a valid phone number!");
xPhone.requestFocus();
return;
}
PhoneAuthProvider.getInstance().verifyPhoneNumber(
xMobileNumber, // Phone number to verify
60, // Timeout duration
TimeUnit.SECONDS, // Unit of timeout
(Executor) this, // Activity (for callback binding) //NOT SURE ABOUT THIS
mCallbacks); // OnVerificationStateChangedCallbacks
}
PhoneAuthProvider.OnVerificationStateChangedCallbacks mCallbacks=new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
@Override
public void onVerificationCompleted(@NonNull PhoneAuthCredential phoneAuthCredential) {
}
@Override
public void onVerificationFailed(@NonNull FirebaseException e) {
}
@Override
public void onCodeSent(@NonNull String s, @NonNull PhoneAuthProvider.ForceResendingToken forceResendingToken) {
super.onCodeSent(s, forceResendingToken);
codeSent=s;
}
};
}
My Logcat我的日志猫
LOGCAT:2020-06-10 03:59:44.148 16491-16491/com.example.XX
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.XX, PID: 16491
java.lang.ClassCastException: com.example.XX.SignInFragment cannot be cast to java.util.concurrent.Executor
at com.example.XX.SignInFragment.sendVerificationCode(SignInFragment.java:132)
at com.example.XX.SignInFragment.access$000(SignInFragment.java:29)
at com.example.XX.SignInFragment$1.onClick(SignInFragment.java:65)
at android.view.View.performClick(View.java:7201)
at android.view.View.performClickInternal(View.java:7170)
at android.view.View.access$3500(View.java:806)
at android.view.View$PerformClick.run(View.java:27582)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7695)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:516)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
I know the problem is at the executor portion, it was suggested by the IDE to make use of executor at two places.我知道问题出在执行器部分,IDE 建议在两个地方使用执行器。 Maybe the PhoneAuth method is not for fragments.也许 PhoneAuth 方法不适用于片段。 Can anyone review this or tell an alternate way to implement Firebase Phone Authentication inside a Fragment ONLY.任何人都可以查看此内容或告诉仅在片段内实现 Firebase 电话身份验证的替代方法。
this
used in activity. this
在活动中使用。 In fragment use getActivity
instead of this
在片段中使用getActivity
而不是this
Replace代替
PhoneAuthProvider.getInstance().verifyPhoneNumber(
xMobileNumber, // Phone number to verify
60, // Timeout duration
TimeUnit.SECONDS, // Unit of timeout
(Executor) this, // Activity (for callback binding) //NOT SURE ABOUT THIS
mCallbacks); // OnVerificationStateChangedCallbacks
}
with和
PhoneAuthProvider.getInstance().verifyPhoneNumber(
xMobileNumber, // Phone number to verify
60, // Timeout duration
TimeUnit.SECONDS, // Unit of timeout
getActivity(), // Activity (for callback binding) //NOT SURE ABOUT THIS
mCallbacks); // OnVerificationStateChangedCallbacks
}
UPDATE更新
To avoid app crash check:为避免应用程序崩溃检查:
if (TextUtils.isEmpty(codeSent) || codeSent == null) {
Toast.makeText(this, "Please wait until code received", Toast.LENGTH_SHORT).show();
return;
}
PhoneAuthCredential credential = PhoneAuthProvider.getCredential(codeSent, tOTP);
signInWithPhoneAuthCredential(credential);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.