首页 > 解决方案 > firebaseAuth.getCurrentUser 在第一次调用时返回 null

问题描述

我正在尝试在 MVVM 模型下使用 Firebase 实现登录活动。我使用带有电子邮件和密码的 Firebase 登录来检查用户是否退出数据库。

但是,getCurrentUser 方法总是在第一次调用时返回 NULL。这意味着,当我输入正确的用户名和密码(存​​在于数据库中)并单击登录按钮时,我得到的结果是 NULL。但是当我第二次点击时,它会返回正确的用户 ID。请帮我解决这个问题。太感谢了。

这是我的代码

主要活动:

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

    mUserName = findViewById(R.id.txt_userName);
    mPassword = findViewById(R.id.txt_password);
    mBtnLogin = findViewById(R.id.btn_login);

    mMainActivityViewModels = new ViewModelProvider(this).get(MainActivityViewModels.class);
    mMainActivityViewModels.init();

    mBtnLogin.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            appLogin(mUserName.getText().toString(), mPassword.getText().toString());}
private void appLogin(String userName, String password){
        String userID;
        if(userName.length() == 0 && password.length() == 0){
            Toast.makeText(getApplicationContext(), "User name and Password are incorrect", Toast.LENGTH_LONG).show();

        } else {
            userID = mMainActivityViewModels.signIn(this, userName, password).getValue();
            if(userID == null){
                Toast.makeText(getApplicationContext(), "User name and Password are incorrect", Toast.LENGTH_LONG).show();

            } else {
                Intent homeIntent = new Intent(MainActivity.this, Home.class);
                homeIntent.putExtra("userID", userID);
                startActivity(homeIntent);
            }
}

MainActivityViewModels:

public class MainActivityViewModels extends ViewModel {
private MainActivityRepository mMainActivityRepo;

public void init(){
    mMainActivityRepo = MainActivityRepository.getInstance();
}

public LiveData<String> signIn(Activity activity, String user_name, String pass){
    return mMainActivityRepo.signInWithEmailAndPassword(activity, user_name, pass);


}

MainActivityRepository:

public class MainActivityRepository {
private static MainActivityRepository instance;
private static MutableLiveData<String> userID;
private static FirebaseAuth firebaseAuth;

public static MainActivityRepository getInstance(){
    if(instance == null){
        instance = new MainActivityRepository();
    }

    firebaseAuth = FirebaseAuth.getInstance();
    return instance;
}

public MutableLiveData<String> signInWithEmailAndPassword(Activity activity, String userName, String password){
    public MutableLiveData<String> signInWithEmailAndPassword(Activity activity, String userName, String password){
    firebaseAuth.signInWithEmailAndPassword(userName, password).addOnCompleteListener(activity,
            new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    if(task.isSuccessful()){
                        FirebaseUser user = firebaseAuth.getCurrentUser(); 
                        userID.setValue(user.getUid());

                    } else {
                        System.out.println("Unsuccessful login");
                    }

                }
            }
    );
    return userID;

}

错误:

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.snote, PID: 31470
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object androidx.lifecycle.LiveData.getValue()' on a null object reference
    at com.snote.MainActivity.appLogin(MainActivity.java:34)
    at com.snote.MainActivity.access$200(MainActivity.java:21)
    at com.snote.MainActivity$1.onClick(MainActivity.java:89)

==================================================== ========================== 解决方案

我想出了一个解决方案:

我将在 onStart 方法中添加 AuthStateListener 并确保用户将注销 onStop 方法:

@Override
protected void onStart(){
    super.onStart();
    firebaseAuth.addAuthStateListener(this);

}

@Override
protected void onStop(){
    super.onStop();
    firebaseAuth.signOut();

}

@Override
public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
    if(firebaseAuth.getCurrentUser() != null){
        userID = firebaseAuth.getCurrentUser().getUid();
        Intent homeIntent = new Intent(MainActivity.this, Home.class);
        homeIntent.putExtra("UID", userID);
        startActivity(homeIntent);
    }
}

如果我错了,请纠正我。

标签: androidmvvmfirebase-authentication

解决方案


这可能是 SDK 中的错误。我建议在 GitHub 上归档

您可以做的是使用传递给 onComplete 回调的AuthResult,它应该包含当前用户对象。

FirebaseUser user = task.getResult().getUser();

推荐阅读