单Activity应用中Hilt依赖作用域问题:用户切换后数据未更新
解决方案
方案1:动态获取当前用户,避免固定实例依赖
无需重建Repository,修改实现逻辑,每次获取数据时从FirebaseAuth动态拉取当前登录用户,而非依赖初始化时注入的固定实例。
示例代码:
class UserRepository @Inject constructor( private val firebaseAuth: FirebaseAuth, private val firestore: FirebaseFirestore ) { fun getCurrentUserProfile(): Flow<UserProfile> { // 每次调用都获取最新的当前用户 val currentUser = firebaseAuth.currentUser ?: return flowOf(UserProfile.Empty) return firestore.collection("users") .document(currentUser.uid) .snapshots() .map { snapshot -> snapshot.toObject(UserProfile::class.java) ?: UserProfile.Empty } } }
无论用户切换多少次,每次调用Repository方法都会基于当前登录用户拉取数据,从根源避免旧数据残留。
方案2:自定义用户作用域+子组件,实现用户级依赖重建
创建@UserScoped自定义作用域,定义UserComponent作为MainActivity组件的子组件,将Repository绑定到该作用域。用户登录时创建组件,登出时销毁,下次登录重建组件实例,从而刷新Repository。
步骤1:定义自定义作用域
@Retention(AnnotationRetention.RUNTIME) @Scope annotation class UserScoped
步骤2:创建UserComponent接口
@UserScoped @Component( dependencies = [MainActivityComponent::class], modules = [UserModule::class] ) interface UserComponent { fun inject(homeScreen: HomeScreen) @Component.Factory interface Factory { fun create( parent: MainActivityComponent, @BindsInstance userId: String ): UserComponent } }
步骤3:创建UserModule提供用户级Repository
@Module class UserModule { @Provides @UserScoped fun provideUserRepository( firebaseAuth: FirebaseAuth, firestore: FirebaseFirestore, userId: String ): UserRepository { return UserRepository(firebaseAuth, firestore, userId) } }
步骤4:在MainActivity中管理组件生命周期
@AndroidEntryPoint class MainActivity : ComponentActivity() { private var userComponent: UserComponent? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { MyAppTheme { val authState = remember { firebaseAuth.authStateFlow } LaunchedEffect(authState) { authState.collect { user -> userComponent = if (user == null) { null // 登出时销毁组件 } else { // 登录时创建新组件 DaggerUserComponent.factory() .create(this@MainActivity.component, user.uid) } } } NavHost(navController = navController, startDestination = "login") { composable(route = "home") { userComponent?.inject(this) HomeScreen(repository = userComponent?.userRepository) } // 其他路由... } } } } }
方案3:监听Auth状态,自动刷新Repository数据
在Repository中监听FirebaseAuth的用户状态变化,用户切换时自动拉取新用户数据,无需重建Repository。
示例代码:
class UserRepository @Inject constructor( private val firebaseAuth: FirebaseAuth, private val firestore: FirebaseFirestore ) { private val _currentUserProfile = MutableStateFlow<UserProfile>(UserProfile.Empty) val currentUserProfile: StateFlow<UserProfile> = _currentUserProfile init { // 监听用户状态变更 firebaseAuth.addAuthStateListener { auth -> val currentUser = auth.currentUser if (currentUser != null) { fetchUserProfile(currentUser.uid) } else { _currentUserProfile.value = UserProfile.Empty } } } private fun fetchUserProfile(userId: String) { firestore.collection("users") .document(userId) .addSnapshotListener { snapshot, _ -> snapshot?.toObject(UserProfile::class.java)?.let { _currentUserProfile.value = it } } } }
后续在HomeScreen中监听currentUserProfile的状态流,即可自动更新UI数据。
内容的提问来源于stack exchange,提问作者James Olrog
相关产品推荐
相关产品推荐

