如何正确使用 firebase-firestore 异步调用

How to properly use firebase-firestore async calls

我正在做我的 Final Year Project,我真的很难决定我应该使用 Kotlin 的回调还是协程。我为 firebase 创建了单独的模块,它的所有操作都在那里完成,无论是数据检索还是任何其他功能。

问题是,每当我 return 用户从它的函数 return null 由于异步调用而我理解它时,然后我使用回调它像这样:

fun getUserAsModel(callback: (User) -> Unit) {
    FirebaseAuth.getInstance().uid?.let {
        firestore.collection(Constants.FireCollections.USERS)
            .document(it)
            .get()
            .addOnSuccessListener { it1 ->
                val user = it1.toObject(User::class.java)?.let { it2 ->
                    callback(it2)
                }
            }
            .addOnFailureListener {
                Log.e(TAG, "In userModel()->", it)
                it.stackTrace
            }
    }
}

但我在很多形式中看到我应该使用协程,现在我正在使用这种方法,但它不起作用:

fun getUser () : User? {
    var user:User? = null
    val collection = firestore.collection(Constants.FireCollections.USERS)
    val document = collection.document(FirebaseAuthRepository().getCurrentUserId())
    try {
        scope.launch {
            val snapshot = document.get().await()
            user = snapshot.toObject(User::class.java)
        }
    } catch (e:FirebaseFirestoreException) {
        Log.e(TAG, "In getUser() -> " ,e)
        e.stackTrace
    }
    return user
}

我仍然卡住了,因为每次我使用 getUser() 我都需要启动协同程序的范围,这真的让代码变得很糟糕。

我想了解您的解决方案,我应该如何正确实施它。谢谢

您正在重新创建与异步调用相同的问题,因为协程是异步启动的。使用协程的正确方法是使它成为一个挂起函数并直接 return 用户,而无需在此函数内启动另一个协程。

函数应如下所示:

suspend fun getUser () : User? {
    val collection = firestore.collection(Constants.FireCollections.USERS)
    val document = collection.document(FirebaseAuthRepository().getCurrentUserId())
    return try { 
        val snapshot = document.get().await()
        snapshot.toObject(User::class.java)
    } catch (e: FirebaseFirestoreException) {
        Log.e(TAG, "In getUser() -> ", e)
        null
    }
}

回调与协程是一个偏好问题。协程学习起来并不简单,但一旦你学会了,你的代码就会 cleaner-looking 并且更容易理解。