简体   繁体   English

在 Fragment android 内使用 Firebase 电话认证

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM