Kotlin报Property items should be initialized before get错误如何解决
错误原因
Firestore的get()属于异步操作,addOnSuccessListener的回调函数会在数据库查询(网络请求/本地缓存读取)完成后才会执行。而你写的Log.i("items",items.toString())是主线程同步执行的代码,运行顺序早于回调赋值逻辑,所以读取items时它还没有完成初始化,触发报错。
解决方案
以下是3种常用的可行写法:
- 方案1:把所有用到
items的逻辑都放到成功回调内部(最推荐,无额外依赖)
db.collection("Testdatabase").get().addOnSuccessListener{ snap-> val items = snap.size() // 所有需要使用items的逻辑都写在这里,比如打印日志、更新UI等 Log.i("items", items.toString()) }
这种写法不需要额外声明全局的items变量,从根源上避免未初始化问题。
- 方案2:使用Kotlin协程将异步操作转为同步写法,避免多层回调嵌套
需要引入Firestore KTX扩展依赖,在协程作用域中执行:
// 以lifecycleScope为例,也可以用viewModelScope等其他协程作用域 lifecycleScope.launch { try { val snap = db.collection("Testdatabase").get().await() val items = snap.size() Log.i("items", items.toString()) // 后续使用items的逻辑 } catch (e: Exception) { // 处理查询失败的异常 } }
- 方案3:如果确实需要全局变量存储结果,给变量设置默认值,同时保证仅在赋值完成后读取
// 设置默认值-1代表还未完成查询,替代notNull声明 var items: Int = -1 db.collection("Testdatabase").get().addOnSuccessListener{ snap-> items = snap.size() // 此处可以通知其他逻辑items已经完成赋值,可以使用 Log.i("items", items.toString()) } // 注意:不要在回调之外立刻读取items,此时值还为初始值-1
注意:无论用哪种写法,都要保证读取
items的时机是在数据库查询完成之后,绝对不要在异步回调外部同步读取异步任务的返回结果。
内容的提问来源于stack exchange,提问作者sooyeon
相关产品推荐
相关产品推荐

