Firebase Auth退出登录后重启App仍保留currentUser问题求助
问题修复方案
核心问题分析
- Google账号登出不彻底:使用Google登录的用户,仅调用了
googleSignInClient.signOut(),未同步调用firebaseAuth.signOut(),导致Firebase Auth实例仍保留用户会话信息,重启App后currentUser不为null。 - SplashActivity重复启动页面:
onStart()的延迟任务中连续调用两次startActivity(intent),属于冗余代码,会导致目标Activity被重复启动。
修复步骤
1. 完善Google账号登出逻辑
在Google登出成功的回调中,额外调用firebaseAuth.signOut(),确保Firebase Auth的会话被彻底清除。
2. 移除SplashActivity中的重复启动代码
删除重复的startActivity(intent)调用,避免页面重复启动。
3. 可选:改用Firebase Auth状态监听器(更可靠)
使用Auth状态监听器替代固定延迟检查,能实时准确获取用户登录状态,避免延迟导致的判断误差。
修改后的代码
1. ProfileFragment登出逻辑修改
private const val TAG = "ProfileFragment" @AndroidEntryPoint class ProfileFragment : Fragment() { private var _binding: FragmentProfileBinding? = null private val binding get() = _binding!! @Inject lateinit var firebaseAuth: FirebaseAuth private lateinit var googleSignInClient: GoogleSignInClient private val viewModel by viewModels<CredentialsViewModel>() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { _binding = FragmentProfileBinding.inflate(inflater, container, false) return binding.root } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) binding.logoutButton.setOnClickListener { val currentUser = firebaseAuth.currentUser ?: return@setOnClickListener for (i in 0 until currentUser.providerData.size) { when (currentUser.providerData[i].providerId) { "google.com" -> { Log.d(TAG, "onViewCreated: provider is ${currentUser.providerData[i].providerId}") googleSignInClient = GoogleSignIn.getClient( requireActivity(), viewModel.getGoogleSignInOptions() ) googleSignInClient.signOut().addOnCompleteListener { task -> if (task.isSuccessful) { // 同步清除Firebase Auth会话 firebaseAuth.signOut() redirectToMainActivity() } } } "password" -> { Log.d(TAG, "onViewCreated: ${currentUser.providerData[i].providerId}") firebaseAuth.signOut() redirectToMainActivity() } else -> { Log.d(TAG, "onViewCreated: ${currentUser.providerData[i].providerId}") firebaseAuth.signOut() // 兜底清除会话 redirectToMainActivity() } } } } } private fun redirectToMainActivity() { val intent = Intent(requireContext(), MainActivity::class.java) intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK) startActivity(intent) requireActivity().finish() } override fun onDestroy() { super.onDestroy() _binding = null } }
2. SplashActivity修改(移除重复启动+可选添加状态监听)
private const val TAG = "SplashActivity" @AndroidEntryPoint class SplashActivity : AppCompatActivity() { private lateinit var binding: ActivitySplashBinding @Inject lateinit var firebaseAuth: FirebaseAuth private var authStateListener: FirebaseAuth.AuthStateListener? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivitySplashBinding.inflate(layoutInflater) setContentView(binding.root) val typeface = ResourcesCompat.getFont(this, R.font.blacklist) val animation = AnimationUtils.loadAnimation(this, R.anim.my_anim) binding.apply { splashTextView.typeface = typeface splashTextView.animation = animation } // 初始化Auth状态监听器(可选,替代延迟检查) authStateListener = FirebaseAuth.AuthStateListener { auth -> val user = auth.currentUser Handler(Looper.getMainLooper()).postDelayed({ val intent = if (user == null) { Intent(this@SplashActivity, MainActivity::class.java) } else { Intent(this@SplashActivity, HomeActivity::class.java) } startActivity(intent) finish() }, 3000) } } override fun onStart() { super.onStart() // 添加监听器(如果用状态监听的话) authStateListener?.let { firebaseAuth.addAuthStateListener(it) } // 如果不用状态监听,保留原逻辑但移除重复启动 /* Handler(Looper.getMainLooper()).postDelayed({ val intent = if(firebaseAuth.currentUser == null) { Intent(this@SplashActivity, MainActivity::class.java) } else { Intent(this@SplashActivity, HomeActivity::class.java) } startActivity(intent) finish() }, 3000) */ } override fun onStop() { super.onStop() // 移除监听器,避免内存泄漏 authStateListener?.let { firebaseAuth.removeAuthStateListener(it) } } }
内容的提问来源于stack exchange,提问作者Dr Mido
相关产品推荐
相关产品推荐

