【问题标题】:Android Firebase logout app crashes AFTER I logoutAndroid Firebase 注销应用程序在我注销后崩溃
【发布时间】:2021-08-03 17:13:08
【问题描述】:

我有我在其中处理注销的 MainActivity。问题是我注销后,应用程序在verifyUserExistance() 处崩溃:

String userID = Objects.requireNonNull(mAuth.getCurrentUser()).getUid();

这给出了:

E/AndroidRuntime: 致命异常: main 进程:com.google.firebase.quickstart.auth,PID:8459 java.lang.NullPointerException 在 java.util.Objects.requireNonNull(Objects.java:203) 在 com.google.firebase.quickstart.auth.social.Main_Chat_Activity$3.lambda$null$1$Main_Chat_Activity$3(Main_Chat_Activity.java:372) 在 com.google.firebase.quickstart.auth.social.-$$Lambda$Main_Chat_Activity$3$87CwjFnoJAhucBGNsLP_MxK833o.onComplete(未知来源:2) 在 com.google.android.gms.tasks.zzj.run(com.google.android.gms:play-services-tasks@@17.2.0:4) 在 android.os.Handler.handleCallback(Handler.java:873) 在 android.os.Handler.dispatchMessage(Handler.java:99) 在 android.os.Looper.loop(Looper.java:214) 在 android.app.ActivityThread.main(ActivityThread.java:7050) 在 java.lang.reflect.Method.invoke(本机方法) 在 com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)

下面是我使用的代码:

@Override
protected void onStart() {
    super.onStart();
    usersRef.child(mAuth.getCurrentUser().getUid()).addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot snapshot) {
            if (!snapshot.hasChild("name"))
            {
                sendUserToLoginActivity();
            }
        }

        @Override
        public void onCancelled(@NonNull DatabaseError error) {

        }
    });
    if (mAuth == null || currentUser == null || mAuth.getCurrentUser().getUid() == null ){
        finish();
        sendUserToLoginActivity();
    }
    else {
        if(mAuth.getCurrentUser().getProviderId() == "google.com"){
            user.setmGoogleSignInClient(mGoogleSignInClient);
        }
        user.setMauth(mAuth);
        if (loginOutFlag>-1)
            verifyUserExistence();
    }
    checkLocation();
    if (isNew!=null)
    {
        if (isNew.equals("true")){
            sendUserToSettingsActivity();
        }
    }
}

方法verifyUserExistance是;

 private void verifyUserExistence() {
    if (!verified && loginOutFlag > -1) {
        String currentUserID = mAuth.getCurrentUser().getUid();
        try {


            rootRef.child("Users").child(currentUserID).addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

                    if (dataSnapshot.child("name").exists()) {
                        loginOutFlag = 1;
                        Toast.makeText(Main_Chat_Activity.this, "Welcome" + dataSnapshot.child("name").getValue().toString(), Toast.LENGTH_SHORT).show();
                        Log.w("Reportname:", dataSnapshot.child("name").getValue().toString());
                        Calendar cal = Calendar.getInstance();
                        final String timeNDate = cal.getTime().toString();
                        HashMap<String, Object> profileMap = new HashMap<>();
                        profileMap.put("connection", timeNDate);
                        rootRef.child("Users").child(currentUserID).updateChildren(profileMap)
                                .addOnCompleteListener(task ->
                                {
                                    if (task.isSuccessful()) {
                                        Toast.makeText(Main_Chat_Activity.this, "Success ", Toast.LENGTH_SHORT).show();
                                        verified = true;
                                        FirebaseMessaging.getInstance().getToken()
                                                .addOnCompleteListener(task13 -> {
                                                    String userID = Objects.requireNonNull(mAuth.getCurrentUser()).getUid();
                                                    if (!task13.isSuccessful()) {
                                                        Log.w("FCM", "Fetching FCM registration token failed", task13.getException());
                                                        return;
                                                    }

                                                    // Get new FCM registration token
                                                    String deviceToken = task13.getResult();

                                                    // Log and toast

                                                    Log.d("FCM", deviceToken);
                                                    Toast.makeText(Main_Chat_Activity.this, deviceToken, Toast.LENGTH_SHORT).show();
                                                    final int[] no = {0};
                                                    DatabaseReference tokens = usersRef.child(userID).child("device_tokens");
                                                    ValueEventListener valueEventListener = new ValueEventListener() {
                                                        @Override
                                                        public void onDataChange(@NonNull DataSnapshot snapshot) {
                                                            no[0] = (int) snapshot.getChildrenCount();
                                                        }

                                                        @Override
                                                        public void onCancelled(@NonNull DatabaseError error) {

                                                        }
                                                    };
                                                    tokens.addListenerForSingleValueEvent(valueEventListener);
                                                    String devName = "device" + no[0];
                                                    String token = deviceToken.split(":")[1];
                                                    usersRef.child(userID).child("device_tokens").child(devName)
                                                            .setValue(token)
                                                            .addOnCompleteListener(task12 -> {
                                                                if (task12.isSuccessful()) {
                                                                    Toast.makeText(Main_Chat_Activity.this, "Token updated succesfully.", Toast.LENGTH_LONG).show();
                                                                }
                                                            });

                                                });
                                    } else {
                                        String errorMSG = Objects.requireNonNull(task.getException()).toString();
                                        //user.setMauth(null);
                                        Toast.makeText(Main_Chat_Activity.this, "Error : " + errorMSG, Toast.LENGTH_SHORT).show();
                                    }

                                });

                    }
                }

                @Override
                public void onCancelled(@NonNull DatabaseError databaseError) {

                }
            });
        }
        catch (Exception e)
        {
            Log.d("EXCEPTION", e.toString());
        }
    }


}

这就是我处理注销的方式;

 @Override
public boolean onOptionsItemSelected(MenuItem item) {
    super.onOptionsItemSelected(item);

    if (item.getItemId() == R.id.main_logout_option) {
        updateUserStatus("offline");
        String currentUserID = mAuth.getCurrentUser().getUid();

        rootRef.child("Users").child(currentUserID).addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

                if (dataSnapshot.child("name").exists()) {

                    Calendar cal = Calendar.getInstance();
                    final String timeNDate = cal.getTime().toString();
                    HashMap<String, Object> profileMap = new HashMap<>();
                    profileMap.put("connection", timeNDate);
                    rootRef.child("Users").child(currentUserID).updateChildren(profileMap)
                            .addOnCompleteListener(task ->
                            {
                                if (task.isSuccessful()) {
                                    loginOutFlag = -1;
                                } else {
                                    String errorMSG = Objects.requireNonNull(task.getException()).toString();
                                    Toast.makeText(Main_Chat_Activity.this, "This error : " + errorMSG, Toast.LENGTH_SHORT).show();
                                }
                                mGoogleSignInClient.signOut().addOnCompleteListener(task1 -> {
                                    if (task1.isSuccessful()){
                                        mAuth.signOut(); // very important if you are using firebase.
                                        LoginManager.getInstance().logOut();
                                        sendUserToLoginActivity();
                                        finish();
                                    }
                                });
                            });
                }

            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });

        sendUserToLoginActivity();
    }

    if (item.getItemId() == R.id.main_settings_option) {
        sendUserToSettingsActivity();
    }
    if (item.getItemId() == R.id.main_find_friends_option) {
        sendUserToFindFriendsActivity();
    }
    return true;
}

【问题讨论】:

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


    【解决方案1】:

    问题是我注销后,应用程序崩溃:

    at line String userID = Objects.requireNonNull(mAuth.getCurrentUser()).getUid()
    

    当您注销时,mAuth 对象变为null。因此在这样的对象上调用getCurrentUser(),而不是返回FirebaseUser 对象,它将返回null,因此存在NullPointerExcepetion。

    返回当前登录的 FirebaseUser,如果没有则返回 null。

    因此,解决您的问题的方法是等待异步操作完成,然后立即退出,否则,您将始终得到 NullPointerExcepetion。

    这是一个示例,您可以等到从实时数据库中加载完数据:

    【讨论】:

    • 看到问题是如果 mAuth 为空,那么在 onStart() 方法中它应该将我发送到 loginActivity,因为我使用了if (mAuth == null || currentUser == null || mAuth.getCurrentUser().getUid() == null ){ finish(); sendUserToLoginActivity(); } else { if(mAuth.getCurrentUser().getProviderId() == "google.com"){ user.setmGoogleSignInClient(mGoogleSignInClient); } user.setMauth(mAuth); if (loginOutFlag&gt;-1) verifyUserExistence(); },但它没有。问题真的出自这里。还有其他选择吗?
    • 如果mAuth在onStart()中为null,则表示用户未登录。在对此类对象进行进一步操作之前,您应该检查这一点。不幸的是,除了等待数据之外,没有其他选择。尝试等待数据并告诉我它是否有效。
    • 但 mAuth 为空(或应该为空),因为我退出了。然而在onStart 中,它似乎不是,这就是它错误地调用verifyUserExistance 的原因。
    • 您是否尝试在异步操作完成后退出?
    • 我认为可能还有更多。看,当我单击注销时,UI 更改为 LoginActivity,然后它才会崩溃。但这没有意义。我称为finish() 的活动如何在另一个活动开始后崩溃??
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-12-19
    • 1970-01-01
    • 2012-12-17
    • 2018-06-10
    • 1970-01-01
    • 2018-10-23
    • 2016-12-26
    相关资源
    最近更新 更多