Firebase - 重新打开应用程序后用户注销时应用程序关闭

Posted

技术标签:

【中文标题】Firebase - 重新打开应用程序后用户注销时应用程序关闭【英文标题】:Firebase - App Shuts Down When User Log Out After ReOpening App 【发布时间】:2021-11-23 18:21:14 【问题描述】:

每当我打开应用程序并登录时,它都可以正常工作,而且我可以轻松地从应用程序注销,它会让我回到登录活动.. 但是当我在登录后关闭应用程序并重新打开应用程序然后我注销时,它会让我登录活动然后应用程序关闭。不知道为什么。

这是 Logcat 的截图

这是导致问题的代码 SignupTabFragment.java

if(firebaseAuth.getCurrentUser() != null)
    // Retrieving User Data From Firebase
    userIDFireStore = firebaseAuth.getCurrentUser().getUid();
    DocumentReference documentReference = firestore.collection("users").document(userIDFireStore);
    documentReference.addSnapshotListener(new EventListener<DocumentSnapshot>() 
        @Override
        public void onEvent(@Nullable DocumentSnapshot value, @Nullable FirebaseFirestoreException error) 
            userTypeFirestore = value.getString("userType");
            if(userTypeFirestore.equals("Admin"))
                startActivity(new Intent(getActivity().getApplicationContext(),AdminHomeActivity.class));
                getActivity().finish();
            
            if(userTypeFirestore.equals("Student"))
                startActivity(new Intent(getActivity().getApplicationContext(),HomeActivity.class));
                getActivity().finish();
            
        
    );

HomeActivity.java

public class HomeActivity extends AppCompatActivity 

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

    public void onLogoutClick(View view) 
        // Logout
            FirebaseAuth.getInstance().signOut();
            startActivity(new Intent(getApplicationContext(),LoginActivity.class));
            finish();
    

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) 
        if(keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0)
            finish();
            System.exit(0);
        
        return super.onKeyDown(keyCode, event);
    

LoginActivity.java

public class LoginActivity extends AppCompatActivity 

TabLayout tabLayout;
TabItem tabLogin,tabSignup;
ViewPager viewPager;
int nightModeFlags;
ConstraintLayout constraintLayout;


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

    tabLayout = (TabLayout) findViewById(R.id.tab_layout);
    tabLogin = (TabItem) findViewById(R.id.tab_login);
    tabSignup = (TabItem) findViewById(R.id.tab_signup);
    viewPager = (ViewPager) findViewById(R.id.view_pager);
    constraintLayout = (ConstraintLayout) findViewById(R.id.constraint_backgrond);

    // To Change Constraint Layout Background in Night Mode
    nightModeFlags = constraintLayout.getContext().getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
    switch(nightModeFlags)
        case Configuration.UI_MODE_NIGHT_YES:
            constraintLayout.setBackgroundResource(R.drawable.view_bg_night);
            break;
        case Configuration.UI_MODE_NIGHT_NO:
            constraintLayout.setBackgroundResource(R.drawable.view_bg);
            break;
        case Configuration.UI_MODE_NIGHT_UNDEFINED:
            constraintLayout.setBackgroundResource(R.drawable.view_bg);
            break;
    


//        tabLayout.addTab(tabLayout.newTab().setText("Login"));
//        tabLayout.addTab(tabLayout.newTab().setText("Sign Up"));
          tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);

    final LoginAdapter adapter = new LoginAdapter(getSupportFragmentManager(), this,tabLayout.getTabCount());
    viewPager.setAdapter(adapter);
    viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));

    // Changing Fragments When The Tab is Selected or Clicked.
    tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() 
        @Override
        public void onTabSelected(TabLayout.Tab tab) 
            viewPager.setCurrentItem(tab.getPosition());
        

        @Override
        public void onTabUnselected(TabLayout.Tab tab) 

        

【问题讨论】:

你能更新你的登录活动代码吗? 首先,问题出在value.getString("userType") 这一行,因为value 此处为空,您错过了对可空项目的空检查。第二,问题在SignUpTabFragment,你分享了@98​​7654329@,这两个是一样的吗? 请编辑您的问题并将您的数据库结构添加为 JSON 文件。您可以通过单击 Firebase Console 的溢出菜单 (⠇) 中的导出 JSON 来简单地获取它。请回复@AlexMamo @LalitFauzdar 是的,我使用了分片,一个片段用于登录,一个用于注册,并将它们组合到 LoginActivity。第二件事我已经设置了条件 if(firebaseAuth.getUser() != null) 只有当有任何用户登录时它才会为真。所以基本上它不应该在我注销时执行,最后 value.getString("userType) 我在 FireStore 数据库中有那个值。我想根据他们的 userType 分离用户并在他们打开应用程序时将它们发送到他们的活动。并且是的 ClassName 是 SignupTabFragment 这是我的打字错误。 @charlie.7 当然。 【参考方案1】:

您的安全规则很可能要求用户登录后才能从/users/$uid 读取自己的文档。当您注销用户时,该条件不再满足 - 因此您的 onEvent 被调用并出现错误。

要解决的第一个问题是处理传递给onEventerroronEvent 总是被 either DocumentSnapshot 或错误调用,您需要处理这两种情况。例如:

public void onEvent(@Nullable DocumentSnapshot value, @Nullable FirebaseFirestoreException error) 
  if (error == null) 
    userTypeFirestore = value.getString("userType");
    if(userTypeFirestore.equals("Admin"))
        startActivity(new Intent(getActivity().getApplicationContext(),AdminHomeActivity.class));
        getActivity().finish();
    
    if(userTypeFirestore.equals("Student"))
        startActivity(new Intent(getActivity().getApplicationContext(),HomeActivity.class));
        getActivity().finish();
    
  
  else 
    Log.e("Firestore", "Error listening to user data", error);
  


为了首先防止发生此错误,您需要在注销用户之前remove the listener。

【讨论】:

但是为什么不再满足此条件,因为当用户从应用程序注销并返回登录页面时,条件 if(firebaseAuth.getCurrentUser() != null) 应该为 False,因为现在没有用户登录后它甚至不应该执行该条件内的代码 还有一件事,应用程序刚刚关闭,当我再次重新打开时,它显示我的登录活动完全正常 您正在附加一个永久侦听器,因此它会一直侦听直到您将其删除,或者进程停止(这就是重新启动工作的原因)。为防止出现错误,请在注销用户之前移除监听器。 你能帮我怎么做吗,我的意思是如何删除监听器 非常感谢您为我指明了正确的道路! :)

以上是关于Firebase - 重新打开应用程序后用户注销时应用程序关闭的主要内容,如果未能解决你的问题,请参考以下文章

注销后,身份验证firebase会记住我

注销后清除 Firebase 持久性

如果用户第二次登录,使用 Firebase 打开不同的活动

firebase.auth().signOut() 在单击注销后未重定向回 mainNav

Redux/Firebase - 在状态中收到 uid 后组件不更新

注销Firebase经过身份验证的用户后写入Firestore