如何安全处理Firebase Get方法访问不存在数据的问题
问题分析与解决
崩溃原因
- 异步回调异常不受外层try-catch管辖:Firebase的
get()是异步操作,addOnSuccessListener的回调会在get()执行完成后才触发,外层的try-catch在回调执行前就已经运行完毕,所以回调里的异常根本无法被外层捕获。 - 强制类型转换触发空指针:当输入的密钥对应的数据库节点不存在时,
it.child("Code").value会返回null,你用as String强制将null转换为非空String类型,直接触发NullPointerException导致应用崩溃。
修复方案
针对上述问题,修改代码如下:
fun joinFinalised(newEmail: String, code: String) { if (code.isEmpty()){ Toast.makeText(this, "No code entered", Toast.LENGTH_SHORT).show() } else { fDBRef.child(newEmail.replace(".","~dot~")).get().addOnSuccessListener { snapshot -> // 先检查目标节点是否存在 if (!snapshot.exists()) { Toast.makeText(this, "Join failed", Toast.LENGTH_SHORT).show() return@addOnSuccessListener } // 安全获取Code值,避免空指针 val dbCode = snapshot.child("Code").value as? String if (dbCode != null && code == dbCode) { // 同样安全获取Email值 val dbEmail = snapshot.child("Email").value as? String dbEmail?.let { email = it fDBRef.child(it.replace(".","~dot~")).setValue(newCrew) displayData() } ?: run { Toast.makeText(this, "Join failed", Toast.LENGTH_SHORT).show() } } else { Toast.makeText(this, "Join failed", Toast.LENGTH_SHORT).show() } }.addOnFailureListener{ Toast.makeText(this, "Join failed", Toast.LENGTH_SHORT).show() } } }
关键改动说明
- 节点存在性校验:用
snapshot.exists()检查当前查询的节点是否存在,不存在直接提示失败并终止回调逻辑。 - 安全类型转换:用
as? String替代as String,当value为null时会返回null而非抛出异常。 - 空值前置判断:在使用数据库返回的值前先校验是否为null,避免后续操作触发空指针。
- 移除无效外层try-catch:它无法捕获异步回调里的异常,留着只会造成误解。
内容的提问来源于stack exchange,提问作者Icy
相关产品推荐
相关产品推荐

