【发布时间】:2022-09-28 19:35:58
【问题描述】:
使用 Firebase/Firestore API 时如何防止深度嵌套的回调?
Py app 一步一步调用firestore api,当onSuccess 和onFailed 时我需要做一些处理。
例如,它需要 5 个步骤。为了进行下一步,它需要参考 pre-call api 的结果。
第一步:getA() // get A Data from firestore
第二步:if(resultGetA.isSuccess) getB() else updateC()
第三步:if(resultGetB.isSuccess) addD()
第四步:if(resultAddD.isSuccess) updateE()
第五步:if(resultUpdateE.isSuccess) getF()
kotlin 代码示例
这只是解释我的问题的示例来源, 但我的应用程序的代码类似这样:(
fun callHellExample1(email:String, pass:String, model:UserDataModel) {
val collectRef = Firebase.firestore.collection(\"A\")
val auth = Firebase.auth
auth.createUserWithEmailAndPassword(email, pass).addOnCompleteListener { createTask ->
if (createTask.isSuccessful) {
auth.signInWithEmailAndPassword(email, pass).addOnCompleteListener { signInTask ->
if (signInTask.isSuccessful) {
collectRef.add(model).addOnCompleteListener {
Toast.makeText(this, \"complete create account\", Toast.LENGTH_SHORT).show()
}
} else {
Toast.makeText(this, \"failed create account in Step 2\", Toast.LENGTH_SHORT).show()
}
}
} else {
Toast.makeText(this, \"failed create account in Step 1\", Toast.LENGTH_SHORT).show()
}
}
}
fun callHellExample2(callback : (Boolean)-> Unit) {
val collectRef = Firebase.firestore.collection(\"A\")
val auth = Firebase.auth
collectRef.document(\"A\").get().addOnCompleteListener { resultA ->
if(resultA.isSuccessful){
collectRef.document(\"B\").get().addOnCompleteListener { resultB ->
if(resultB.isSuccessful){
collectRef.add(\"D\").addOnCompleteListener { resultD ->
if(resultD.isSuccessful){
collectRef.document(\"E\").update(\"someFiled\", \"someValue\").addOnCompleteListener { resultE ->
if(resultE.isSuccessful){
collectRef.document(\"F\").get().addOnCompleteListener {
auth.signOut()
callback(true)
}
}
}
}
}
}else{
Toast.makeText(this, \"getB ... isSuccessful? = ${resultB.isSuccessful}\", Toast.LENGTH_SHORT).show()
}
}
}else{
collectRef.document(\"C\").update(\"someFiled\", \"someValue\").addOnCompleteListener { resultC ->
Toast.makeText(this, \"update C ... isSuccessful? = ${resultC.isSuccessful}\", Toast.LENGTH_SHORT).show()
}
}
}
}
所以我尝试通过协程使用。但我找不到关于 firestore api 的逃生回调地狱
我试过这样(示例1)。但它类似于回调地狱。 我想检查它是否成功。
await() 返回不是Task<AuthResult>。它只是返回AuthResult
但AuthResult 不包含isSuccessful 变量
fun example1ByCoroutine(email:String, pass:String, mode:UserModel){
CoroutineScope(Dispatchers.IO).launch {
try{
auth.createUserWithEmailAndPassword(email, pass).await()
try{
auth.signInWithEmailAndPassword(email, pass).await()
try{
collectRef.add(model).await()
withContext(Dispatchers.Main){
Toast.makeText(this, \"complete create account\", Toast.LENGTH_SHORT).show()
}
}catch (e: Exception){
Toast.makeText(this, \"failed create account in Step 3\", Toast.LENGTH_SHORT).show()
}
}catch (e: Exception){
Toast.makeText(this, \"failed create account in Step 2\", Toast.LENGTH_SHORT).show()
}
}catch (e: Exception){
Toast.makeText(this, \"failed create account in Step 1\", Toast.LENGTH_SHORT).show()
}
}
}
示例 2 无法显示 toast 因为也无法检查 isSuccessful。 不是返回任务。它只是返回 DocumentSnapShot
我期待你的回复。 谢谢!
ps)如果可以访问isSuccessful,代码可以这样编辑
fun example1ByCoroutine(email:String, pass:String, mode:UserModel){
CoroutineScope(Dispatchers.IO).launch {
if(!auth.createUserWithEmailAndPassword(email, pass).await().isSuccessful){
Toast.makeText(this, \"failed create account in Step 1\", Toast.LENGTH_SHORT).show()
return@launch
}
if(!auth.signInWithEmailAndPassword(email, pass).await().isSuccessful){
Toast.makeText(this, \"failed create account in Step 2\", Toast.LENGTH_SHORT).show()
return@launch
}
if(collectRef.add(model).await().isSuccessful){
Toast.makeText(this, \"failed create account in Step 3\", Toast.LENGTH_SHORT).show()
return@launch
}
withContext(Dispatchers.Main){
Toast.makeText(this, \"complete create account\", Toast.LENGTH_SHORT).show()
}
}
}
-
这段代码中究竟有什么不能按您期望的方式工作?告诉我们共享代码有什么问题。你有什么错误吗?
标签: android firebase kotlin google-cloud-firestore kotlin-coroutines