提问人:Collaxd 提问时间:11/17/2023 最后编辑:Frank van PuffelenCollaxd 更新时间:11/17/2023 访问量:19
使用 Firebase 和 Kotlin 协程在 Android 中向 flatMapLatest 添加加载状态
Adding Loading States to flatMapLatest in Android with Firebase and Kotlin Coroutines
问:
我正在开发一个利用 Firebase 进行身份验证和数据存储的 Android 项目。该项目遵循 Firebase 文档中的 MakeItSoApp 模型,并通过捕获错误的全局类处理 Crashlytics 错误。出于这个原因,我不太担心应用程序中 API 调用的 try-catch 块,因为它们将在稍后处理。
话虽如此,我的代码一直运行良好。它有一个用户,我需要读取的所有项目都有一个“userId”字段,该字段对应于将其保存在数据库中的用户。
下面是用户结构的示例:
class AccountServiceImpl @Inject constructor(
private val auth: FirebaseAuth
) : AccountService {
override val currentUser: Flow<User>
get() = callbackFlow {
val listener = FirebaseAuth.AuthStateListener { auth ->
this.trySend(auth.currentUser?.let { User(it.uid) } ?: User())
}
auth.addAuthStateListener(listener)
awaitClose { auth.removeAuthStateListener(listener) }
}
}
读取数据继续以这种方式工作。
在服务类中...
@OptIn(ExperimentalCoroutinesApi::class)
class ProductStorageServiceImpl @Inject constructor(
private val firestore: FirebaseFirestore,
private val accountService: AccountService
) : ProductStorageService {
override val products: Flow<List<Product>>
get() = accountService.currentUser.flatMapLatest { user ->
firestore.collection(PRODUCTS_COLLECTION).whereEqualTo(USER_ID_FIELD, user.id)
.dataObjects()
}
override suspend fun add(product: Product) {
val productWithUserId = product.copy(userId = accountService.currentUserId)
firestore.collection(PRODUCTS_COLLECTION).add(productWithUserId).await()
}
}
后跟 ViewModel 类...
var products: Flow<List<Product>> = productStorageService.products
最后,UI 收集项目...
val products by viewModel.products.collectAsStateWithLifecycle(emptyList())
完成此设置后,我遇到了以下问题。首先,我不太明白为什么当我添加产品时,我的阅读屏幕会更新,因为我只在屏幕中收集它,而 flatMapLatest 正在倾听用户的声音。这让我感到困惑,但它只是有效。现在,我想在我的流程中添加一个加载状态,类似于著名的 Resources 类:
sealed class Resource<T>(
val data: T? = null,
val message: String? = null,
) {
class Success<T>(data: T) : Resource<T>(data)
class Loading<T> : Resource<T>()
}
但是,我没有 Flow;我有一个flatMapLatest...
accountService.currentUser.flatMapLatest
...我唯一有流程的地方是在用户中,但我认为这是不正确的,而且考虑到数据来自另一个类,实际上是不可能的。 提前感谢您的任何指导或建议!
答: 暂无答案
评论
Resource