You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Firebase Auth退出登录后重启App仍保留currentUser问题求助

问题修复方案

核心问题分析

  1. Google账号登出不彻底:使用Google登录的用户,仅调用了googleSignInClient.signOut(),未同步调用firebaseAuth.signOut(),导致Firebase Auth实例仍保留用户会话信息,重启App后currentUser不为null。
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 21:15:34