Firestore回调仍返回数据库空值问题排查
处理Firestore异步读取返回空值问题
为处理Firestore返回的异步数据创建了回调函数,Firestore控制台安全规则配置正确、应用与数据库连接正常,但始终获取到空值。
回调接口代码
public interface Callback { void myResponseCallback(String result); }
实现代码
FirebaseFirestore db = FirebaseFirestore.getInstance(); DocumentReference docRef = db.collection("usuarios") .document("idtest"); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_menu); tvMenu = findViewById(R.id.tvMainMenu); btOpenOs = findViewById(R.id.btNewOs); } public void readDataFromFirestore(Callback callback){ //应用似乎根本没进入这段代码,就像卡在第一个IF判断 docRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() { @Override public void onComplete(@NonNull Task<DocumentSnapshot> task) { if (task.isSuccessful()) { DocumentSnapshot document = task.getResult(); if (document.exists()) { dbValue = document.getString("palavra"); //tvMenu.setText(dbValue); 无效 Toast.makeText(MenuActivity.this, "String Value: " + document.getString("palavra"), Toast.LENGTH_SHORT).show(); } } callback.myResponseCallback(dbValue); } }); } public void setDataFromFirestore() { readDataFromFirestore(new Callback() { @Override public void myResponseCallback(String result) { tvMenu.setText(result); //返回null Toast.makeText(MenuActivity.this, "Result: " + result, Toast.LENGTH_SHORT).show(); } }); } public void openOsActivity(View view) { /* Intent osIntent = new Intent(this, OsActivity.class); startActivity(osIntent);*/ setDataFromFirestore(); }
问题现象
setDataFromFirestore()中的Toast显示“Result: null”,尝试读取的Firestore集合字段如下:
补充调试信息
调试结果同样为null:
问题排查与修复方案
1. 核心错误:回调调用时机与变量初始化问题
当前代码中callback.myResponseCallback(dbValue)的调用位置不合理,且dbValue未做局部初始化——若读取流程中任何一步失败(比如文档不存在、task执行失败),都会直接返回初始的null值。另外,即使读取成功,也需确保回调在数据获取完成后再触发。
修改后的readDataFromFirestore方法:
public void readDataFromFirestore(Callback callback){ docRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() { @Override public void onComplete(@NonNull Task<DocumentSnapshot> task) { String result = null; if (task.isSuccessful()) { DocumentSnapshot document = task.getResult(); if (document.exists()) { // 用局部变量存储结果,避免类成员变量的null干扰 result = document.getString("palavra"); Toast.makeText(MenuActivity.this, "String Value: " + result, Toast.LENGTH_SHORT).show(); } else { Toast.makeText(MenuActivity.this, "目标文档不存在", Toast.LENGTH_SHORT).show(); } } else { // 打印错误日志,排查读取失败原因 Log.e("FirestoreReadError", "读取文档失败", task.getException()); Toast.makeText(MenuActivity.this, "读取失败:" + task.getException().getMessage(), Toast.LENGTH_SHORT).show(); } // 最后统一触发回调 callback.myResponseCallback(result); } }); }
2. 额外排查点
- 字段名与文档路径校验:确认
usuarios集合、idtest文档、palavra字段名完全匹配(Firestore区分大小写)。 - 安全规则:测试阶段可临时设置规则为
allow read, write: if true;,排除权限问题。 - 网络与配置:确保设备有网络连接,检查
google-services.json文件是否正确放置在项目中。 - 调试日志:通过
Log打印task的异常信息,能直接定位读取失败的具体原因(比如权限不足、网络错误等)。
调试信息解读
从截图看result为null,说明要么文档不存在、字段名拼写错误,要么task执行失败但未打印错误日志。通过上述修改后的代码,添加错误日志打印后,就能明确具体失败原因。
内容的提问来源于stack exchange,提问作者Leonardo Maito
相关产品推荐
相关产品推荐

