Kotlin集成Firebase、Retrofit、Room应用中FirebaseAuth始终为空问题求助
问题排查与修复方案
1. 修正Firebase初始化逻辑
FirebaseApp初始化不需要在Fragment中执行,默认会在App启动时自动初始化,删除onCreate中的FirebaseApp.initializeApp(context!!);代码即可,避免重复初始化导致的状态异常。
2. 替换单次获取用户逻辑为状态监听
Firebase的用户状态恢复是异步操作,直接在onViewCreated中同步获取currentUser大概率会拿到空值,需要注册FirebaseAuth.AuthStateListener监听登录状态变化,用户状态加载完成后会自动回调。
3. 修正用户判空逻辑和重试逻辑
当前重试按钮调用checkUser时传入的是首次赋值的user变量,就算后续用户状态恢复,该变量还是初始的"null"字符串,导致重试无效,需要在每次判断时重新获取最新的用户状态。
4. 修复后的核心代码示例
DiaryFragment.kt 修改后代码
class DiaryFragment : Fragment(R.layout.fragment_diary), AdapterDetail.OnItemClickListenerDiary{ private var _binding: FragmentDiaryBinding? = null private val binding get() = _binding!! private lateinit var viewModel : DiaryViewModel private lateinit var mAuth : FirebaseAuth // 声明Auth状态监听器 private val authStateListener = FirebaseAuth.AuthStateListener { auth -> val currentUser = auth.currentUser val adapter = AdapterDetail(this) checkUser(currentUser, adapter) } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) mAuth = FirebaseAuth.getInstance() } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) _binding = FragmentDiaryBinding.bind(view) val adapter = AdapterDetail(this) val btnRetryDiary = binding.btnRetryDiary btnRetryDiary.setOnClickListener { // 重试时重新获取最新用户状态 checkUser(mAuth.currentUser, adapter) } } override fun onStart() { super.onStart() // 页面可见时注册监听器 mAuth.addAuthStateListener(authStateListener) } override fun onStop() { super.onStop() // 页面不可见时移除监听器避免内存泄漏 mAuth.removeAuthStateListener(authStateListener) } // 修改checkUser参数直接接收FirebaseUser对象 fun checkUser(user: FirebaseUser?, adapter: AdapterDetail){ if(user != null && user.email != null){ val userEmail = user.email!! Toast.makeText(context, "Already Sign in !", Toast.LENGTH_LONG).show() viewModel = DiaryViewModel(requireContext().applicationContext as Application, RoomUnsplashPhoto(10,"null",null,null,userEmail)) viewModel.getPhotoUser(userEmail)?.observe(viewLifecycleOwner){ adapter.submitData(viewLifecycleOwner.lifecycle, it as PagingData<UnsplashPhoto>) binding.apply { recycleViewDiary.setHasFixedSize(true) recycleViewDiary.itemAnimator = null recycleViewDiary.adapter = adapter } } setHasOptionsMenu(true) }else{ Toast.makeText(context, "¡¡ User esta a null !!", Toast.LENGTH_LONG).show() } } override fun onItemClick(photo: UnsplashPhoto) { val action = DiaryFragmentDirections.actionDiaryFragmentToDetailFragment(photo) findNavController().navigate(action) } override fun onDestroy() { super.onDestroy() _binding = null } }
额外排查点
- 确认进入
DiaryFragment之前用户已经完成了Firebase登录流程,没有调用过signOut或者清除App数据的操作 - 可以升级Firebase BOM版本到最新稳定版,避免旧版本的已知Bug
内容的提问来源于stack exchange,提问作者Manuel Lucas
相关产品推荐
相关产品推荐

