如何正确使用 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 并且更容易理解。
我正在做我的 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 并且更容易理解。