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

时间:2018-02-26 18:33:53

标签: android firebase firebase-realtime-database firebase-authentication

尝试实施firebase身份验证。它在之前工作但在重构之后没有。 所以我尝试在一个单独的类中创建authStateListener,我在那里检查语句。 MainActivity

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

}

在日志中,它会显示标签&#34;检查方法&#34;所以我得出一个结论,告诉主持人它找到了这个方法,但它崩溃了。此外,我认为它可能是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) {

                }
            });

        }


    }


}

对我来说,看起来错误在数据库而不在代码中。

2 个答案:

答案 0 :(得分:1)

如果您的行为与所有用户状态更改相同,则您必须使用“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
             */
        }
    });
 }

或者为每种身份验证方法添加addOnCompleteListener(在这种情况下为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);
        }
    });
  }

答案 1 :(得分:0)

当您使用floowing代码行时:

<div class="actions">
  <button class="scrollDown">
        Scroll down
    </button>
  <button class="scrollUp">
        Scroll up
    </button>
</div>

<div class="panels">
  <div class="panel panel1">
    <div class="panel-bg">
      TEST <br>TESTTEST <br>TESTTEST <br>TESTTEST <br>TESTTEST <br>TEST<br>TESTTEST <br>TESTTEST <br>TESTTEST <br>TESTTEST <br>TEST</div>
  </div>
  <div class="panel panel2">
    <div class="panel-bg">
      TEST <br>TESTTEST <br>TESTTEST <br>TESTTEST <br>TESTTEST <br>TEST<br>TESTTEST <br>TESTTEST <br>TESTTEST <br>TESTTEST <br>TEST
    </div>
  </div>
</div>

这意味着您正在创建new FirebaseAuth.AuthStateListener() {/* ... */} 类的新实例,但未将其分配给变量。

因此,它会为AuthStateListener提供NPE,因为您在值为addAuthStateListener()的对象上使用null。要解决此问题,只需将new FirebaseAuth.AuthStateListener()mAuth字段对齐,然后在任意位置使用它。