如何在Kotlin中传递Firestore查询以在Helper函数的when块区分处理?
解决Firestore查询复用与分支判断问题
你当前代码的核心问题在于,handleQuery的when条件中每次调用db.collection("Users").document(user!!.uid).get()都会生成一个全新的Task<DocumentSnapshot>实例,和传入的query对象引用完全不同,因此永远无法匹配到对应的分支逻辑。
以下是两种可行的解决方案:
方案一:枚举类标识查询类型(适合统一管理查询场景)
这种方式通过枚举定义所有查询类型,将查询任务与类型绑定,让handleQuery能通过枚举值区分处理逻辑。
- 定义查询类型枚举
enum class FirestoreQueryType { GET_USER_PROFILE // 后续新增查询场景直接添加枚举值即可 }
- 封装查询任务与类型的实体类
data class TypedFirestoreQuery( val task: Task<DocumentSnapshot>, val type: FirestoreQueryType )
- 修改
query辅助函数
fun query(typedQuery: TypedFirestoreQuery, auth: FirebaseAuth) { typedQuery.task.addOnCompleteListener { dbTask -> if (dbTask.isSuccessful) { val userDoc = dbTask.result val exists = userDoc?.exists() ?: false handleQuery(typedQuery.type, auth, exists) } else { Log.d("TAG", "Error: ", dbTask.exception) } } }
- 重构
handleQuery函数
private fun handleQuery(queryType: FirestoreQueryType, auth: FirebaseAuth, exists: Boolean = false) { val user = auth.currentUser ?: return // 提前处理null,避免非空断言!! when (queryType) { FirestoreQueryType.GET_USER_PROFILE -> { if (exists) { Log.i("TAG", "User already exists.") } else { Log.e("TAG", "User doesn't exist in db. Attempting to add...") db.collection("Users") .document(user.uid) .set(hashMapOf( "uid" to user.uid, "name" to user.displayName, "email" to user.email, "photoURL" to user.photoUrl )) Log.i("TAG", "User has been added") } } } }
- 调用方式
val getUserQuery = TypedFirestoreQuery( task = db.collection("Users").document(user!!.uid).get(), type = FirestoreQueryType.GET_USER_PROFILE ) utils.query(getUserQuery, auth)
方案二:高阶函数传递处理逻辑(灵活适配不同查询)
如果每个查询的处理逻辑差异较大,不需要统一管理,直接将成功/失败的处理逻辑作为参数传入辅助函数会更简洁。
- 修改
query辅助函数
fun query( task: Task<DocumentSnapshot>, onSuccess: (DocumentSnapshot?, Boolean) -> Unit, onFailure: (Exception) -> Unit ) { task.addOnCompleteListener { dbTask -> if (dbTask.isSuccessful) { val userDoc = dbTask.result val exists = userDoc?.exists() ?: false onSuccess(userDoc, exists) } else { dbTask.exception?.let(onFailure) ?: Log.d("TAG", "Unknown error occurred") } } }
- 调用方式
utils.query( task = db.collection("Users").document(user!!.uid).get(), onSuccess = { _, exists -> val currentUser = auth.currentUser ?: return@query if (exists) { Log.i("TAG", "User already exists.") } else { Log.e("TAG", "User doesn't exist in db. Attempting to add...") db.collection("Users") .document(currentUser.uid) .set(hashMapOf( "uid" to currentUser.uid, "name" to currentUser.displayName, "email" to currentUser.email, "photoURL" to currentUser.photoUrl )) Log.i("TAG", "User has been added") } }, onFailure = { exception -> Log.d("TAG", "Error: ", exception) } )
内容的提问来源于stack exchange,提问作者Connor Smith
相关产品推荐
相关产品推荐

