[英]Null pointer with Firebase auth. How to put listener to another class
嘗試實施 Firebase 身份驗證。 它之前有效,但在重構之后沒有。 所以我試圖在一個單獨的類中創建 authStateListener 並且我正在檢查該語句。 主要活動
IMainPresenter iMainPresenter;
iMainPresenter = new MainPresenter();
iMainPresenter.forwardInfoForLoginAuth(MainActivity.this);
在主持人
public class MainPresenter implements IMainPresenter{
AuthStateListenerUtil authStateListenerUtil;
public MainPresenter() {
this.authStateListenerUtil = authStateListenerUtil;
}
@Override
public void forwardInfoForLoginAuth(Activity mainActivity) {
AuthStateListenerUtil authStateListenerUtils = new AuthStateListenerUtil();
authStateListenerUtils.checkForAuthState(mainActivity);
}
}
並且必須檢查用戶狀態的類,如果用戶未登錄,則必須顯示登錄窗口
public void checkForAuthState(final Activity mainActivity){
Log.v("==========>", " IN CHECK FOR METHOD");
new FirebaseAuth.AuthStateListener() {
@Override
public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
if (FirebaseUserUtil.currentUser != null) {
//Create new user
final String userName = FirebaseUserUtil.currentUser.getDisplayName();
FirebaseUserUtil.getCurrentUserUid(FirebaseUserUtil.userUid)
.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
//the image is still the default one
HashMap<String, String> userMap = new HashMap<>();
userMap.put("name", userName);
userMap.put("image", "default");
userMap.put("thumb_image", "default");
userMap.put("status", "Your status is here...");
FirebaseUserUtil.getCurrentUserUid(FirebaseUserUtil.userUid).setValue(userMap);
}
@Override
public void onCancelled(DatabaseError databaseError) {}
});
} else {
mainActivity.startActivityForResult(
AuthUI.getInstance()
.createSignInIntentBuilder()
.setAvailableProviders(Arrays.asList(
new AuthUI.IdpConfig.EmailBuilder().build(),
new AuthUI.IdpConfig.GoogleBuilder().build()))
.build(),
RC_SIGN_IN);
}
}
};
}
我試圖在一個類中初始化所有主要查詢,以避免在每個活動上重復。 將來我會將它重構為 dagger2,但現在我正在使用常規類。 這就是查詢類
public class FirebaseUserUtil {
public static FirebaseUser currentUser = FirebaseAuth.getInstance().getCurrentUser();
public static String currentUserUid = currentUser.getUid();
public static DatabaseReference getCurrentUserUid(){
return FirebaseDatabase.getInstance().getReference().child("Users").child(currentUserUid);
}
static String getCurrentUserUidString(String uid){
String currentUid = FirebaseDatabase.getInstance().getReference().child("Users").child(currentUserUid).toString();
return currentUid;
}
}
在日志中,它向我顯示了“IN CHECK FOR METHOD”標簽,所以我得出了一個結論,讓演示者找到了這個方法,但它崩潰了。 另外,我認為這可能是 firebase 數據庫的問題。 所以我從那里刪除了所有東西。 因此,如果我理解正確,如果用戶登錄后 firebase 中的表為空,則必須創建一個包含數據的新表。 還有一個問題是我在 logcat 中看到的錯誤沒有給我一個鏈接或信息,錯誤在哪里。
FATAL EXCEPTION: main
Process: com.borisruzanov.russianwives, PID: 6777
java.lang.NullPointerException: Attempt to invoke interface method 'void com.google.firebase.auth.FirebaseAuth$AuthStateListener.onAuthStateChanged(com.google.firebase.auth.FirebaseAuth)' on a null object reference
at com.google.firebase.auth.zzi.run(Unknown Source)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
我的應用類
public class App extends Application{
private DatabaseReference mUserDatabase;
private FirebaseAuth mAuth;
@Override
public void onCreate() {
super.onCreate();
FirebaseDatabase.getInstance().setPersistenceEnabled(true);
/* Picasso */
Picasso.Builder builder = new Picasso.Builder(this);
builder.downloader(new OkHttpDownloader(this, Integer.MAX_VALUE));
Picasso built = builder.build();
built.setIndicatorsEnabled(true);
built.setLoggingEnabled(true);
Picasso.setSingletonInstance(built);
mAuth = FirebaseAuth.getInstance();
if(mAuth.getCurrentUser() != null) {
mUserDatabase = FirebaseDatabase.getInstance()
.getReference().child("Users").child(mAuth.getCurrentUser().getUid());
mUserDatabase.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot != null) {
mUserDatabase.child("online").onDisconnect().setValue(ServerValue.TIMESTAMP);
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
}
對我來說,錯誤似乎是在數據庫中而不是在代碼中。
如果您的行為對於所有用戶狀態更改都相同,則您必須使用“addAuthStateListener”。
對於 AuthStateListener 工作,您必須執行一些方法來進行身份驗證(“signInWithEmailAndPassword”、“createUserWithEmailAndPassword”、...)。
實現 FirebaseAuth 的最佳方法是在該對象的 Presenter 或 Interactor 中保留一個實例,並為所有對象編寫相同的代碼塊:
FirebaseAuth mAuth;
public MainPresenter() {
FirebaseAuth mAuth = FirebaseAuth.getInstance();
mAuth.addAuthStateListener(new FirebaseAuth.AuthStateListener() {
@Override
public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
/*
* put your code here
*/
}
});
}
或者為每種身份驗證方法添加OnCompleteListener(在本例中為signInWithEmailAndPassword)。
public void login(String email, String password){
mAuth.signInWithEmailAndPassword(email, password)
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
Log.d(getClass().getSimpleName(), "signInWithEmail:onComplete:" + task.isSuccessful());
if (task.isSuccessful()) {
Log.w(getClass().getSimpleName(), "signInWithEmail", task.getException());
FirebaseUser user = mAuth.getCurrentUser();
if (user!=null) {
listener.onResult(null, user);
}
} else {
listener.onResult(task.getException(), null);
}
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
listener.onResult(e, null);
}
});
}
當您使用以下代碼行時:
new FirebaseAuth.AuthStateListener() {/* ... */}
這意味着您正在創建AuthStateListener
類的新實例,但沒有將其分配給變量。
所以它給了你一個NPE
因為你在一個值為null
的對象上使用addAuthStateListener()
。 要解決這個問題,只需將new FirebaseAuth.AuthStateListener()
分配給您的mAuth
字段,然后在您想要的任何地方使用它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.