Kotlin中从Firestore数据库读取数值失败求助
问题分析与解决方案
你的问题核心在于Firestore的get()是异步操作,当前的getQuantity函数没有返回值,直接调用它获取不到数据——因为数据还没从网络请求回来,代码就已经执行到后续的quantity100x = quantity100了,所以变量始终是空的。
修复方案1:使用回调函数
修改getQuantity,通过回调返回获取到的数值:
fun getQuantity(name: String, onResult: (Long?) -> Unit) { db.collection("Coin").document(name) .get() .addOnSuccessListener { document -> val coinQuantity = document?.getLong("quantity") onResult(coinQuantity) } .addOnFailureListener { onResult(null) // 处理请求失败的情况 } }
调用时,在回调里处理后续逻辑(比如初始化变量、执行while循环):
cent100.getQuantity("cent100") { quantity -> quantity?.let { var quantity100x = it // 在这里执行依赖quantity100x的while循环逻辑 // 其他硬币的获取也需要放在各自的回调里,或者用合并回调的方式处理多个请求 } }
修复方案2:使用Kotlin协程(推荐)
如果你的项目已经启用协程,可以用await()将异步操作转为同步写法,代码更简洁:
首先确保添加Firestore的协程依赖(如果没加的话),然后修改函数:
import kotlinx.coroutines.tasks.await suspend fun getQuantity(name: String): Long? { return try { val document = db.collection("Coin").document(name).get().await() document.getLong("quantity") } catch (e: Exception) { e.printStackTrace() null } }
然后在协程作用域里调用(比如在viewModelScope、lifecycleScope中):
lifecycleScope.launch { val quantity100 = cent100.getQuantity("cent100") quantity100?.let { var quantity100x = it // 执行while循环等逻辑 } // 其他硬币的获取也可以在这里依次调用 }
关键提醒
- 不要尝试在非异步/协程环境下同步获取Firestore数据,网络请求必须异步处理,否则会导致主线程阻塞或数据为空。
- 处理多个硬币数据时,如果需要所有数据都获取到再执行后续逻辑,可以用
async和awaitAll来并行请求多个文档:
lifecycleScope.launch { val cent100Deferred = async { cent100.getQuantity("cent100") } val cent50Deferred = async { cent50.getQuantity("cent50") } // 其他硬币的deferred val quantity100 = cent100Deferred.await() val quantity50 = cent50Deferred.await() // 拿到所有数据后统一处理逻辑 }
内容的提问来源于stack exchange,提问作者Danilo Volles
相关产品推荐
相关产品推荐

