简体   繁体   English

带有 Firebase 身份验证的空指针。 如何将监听器放到另一个类

[英]Null pointer with Firebase auth. How to put listener to another class

Trying to implement firebase auth.尝试实施 Firebase 身份验证。 It was working before but after refactoring no.它之前有效,但在重构之后没有。 So I tried to create authStateListener in a separate class and there I am checking the statement.所以我试图在一个单独的类中创建 authStateListener 并且我正在检查该语句。 MainActivity主要活动

IMainPresenter iMainPresenter;
        iMainPresenter = new MainPresenter();
        iMainPresenter.forwardInfoForLoginAuth(MainActivity.this);

In presenter在主持人

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);
    }
}

And the class which has to check the state of the user and in case that user is not logged in it has to show login window并且必须检查用户状态的类,如果用户未登录,则必须显示登录窗口

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);
            }
        }
    };
}

I am trying to initialize all main queries in one class to avoid duplicating on each activity.我试图在一个类中初始化所有主要查询,以避免在每个活动上重复。 In future I will refactor it to dagger2 but right now I am using regular classes.将来我会将它重构为 dagger2,但现在我正在使用常规类。 So thats the query class这就是查询类

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 logs it shows me tag "IN CHECK FOR METHOD" so I made a conclusion that threw presenter it finds this method but it crashes.在日志中,它向我显示了“IN CHECK FOR METHOD”标签,所以我得出了一个结论,让演示者找到了这个方法,但它崩溃了。 Also, I thought that it might be a problem with firebase database.另外,我认为这可能是 firebase 数据库的问题。 So I removed everything from there.所以我从那里删除了所有东西。 So if I understand right if the table in firebase is empty after user login it has to create a new table with data.因此,如果我理解正确,如果用户登录后 firebase 中的表为空,则必须创建一个包含数据的新表。 Also the problem is that error which I can see in logcat don't give me a link or information where is the mistake.还有一个问题是我在 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)

My App class我的应用类

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) {

                }
            });

        }


    }


}

For me it looks like that the error is in Database not in code.对我来说,错误似乎是在数据库中而不是在代码中。

If your behavior it's the same for all user state changes you've to use "addAuthStateListener".如果您的行为对于所有用户状态更改都相同,则您必须使用“addAuthStateListener”。

For AuthStateListener works you have to execute some of methods to authenticate ("signInWithEmailAndPassword", "createUserWithEmailAndPassword", ...).对于 AuthStateListener 工作,您必须执行一些方法来进行身份验证(“signInWithEmailAndPassword”、“createUserWithEmailAndPassword”、...)。

The best way to implement a FirebaseAuth is keeping an instance in your Presenter or Interactor of that object and program the same code block for all:实现 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
             */
        }
    });
 }

Or addOnCompleteListener for each method of authentication (in this case signInWithEmailAndPassword).或者为每种身份验证方法添加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);
        }
    });
  }

When you are using the floowing line of code:当您使用以下代码行时:

new FirebaseAuth.AuthStateListener() {/* ... */}

It means that you are creating a new instance of AuthStateListener class but without assignin it to a variable.这意味着您正在创建AuthStateListener类的新实例,但没有将其分配给变量。

So it gives you a NPE because you using addAuthStateListener() on an object that has the value of null .所以它给了你一个NPE因为你在一个值为null的对象上使用addAuthStateListener() To solve this, just asign new FirebaseAuth.AuthStateListener() to you mAuth field and then use it wherever you want.要解决这个问题,只需将new FirebaseAuth.AuthStateListener()分配给您的mAuth字段,然后在您想要的任何地方使用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何修复 Null 指针异常 Firebase Auth - How to fix Null pointer exception Firebase Auth 如何在存储库 class MVVM 中使用 Firebase 身份验证侦听器? - How to use a Firebase auth listener in a repository class MVVM? 如何在自定义 Dialog 类中设置接口和侦听器以将 Facebook 的登录回调传递给 MainActivity 中的 firebase auth? - How to set up Interface and listener in custom Dialog class to pass Facebook's login callback to firebase auth in MainActivity? firebase.auth.FirebaseUser.linkWithCredential 抛出空指针异常 - firebase.auth.FirebaseUser.linkWithCredential throws null pointer exception android webview与https连接和基本身份验证。 如何使这个工作? - android webview with https connection and basic auth. How to get this working? 如何检查用户是否已经在 google auth 中登录。 在安卓中 - How to check if user is already login in google auth. in android 我可以将Firebase ValueEvent侦听器放在Application类中吗 - Can I put Firebase ValueEvent listener in Application class HTML,身份验证。 获取cookie - Html, auth. Getting cookies 另一个类中的空指针异常调用方法 - Null Pointer Exception calling method in another class Firebase 授权用户 null - Firebase auth user null
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM