Firebase判断URL_CARS与URL_PLANES是否存在时始终返回true
解决Firebase数据库节点存在性检测始终返回true的问题
我明白你的困扰——明明感觉节点可能没有数据,但代码却一直提示"DATA EXISTS"。问题出在你判断DataSnapshot是否为null的逻辑上,咱们来一步步梳理:
问题根源
Firebase的DataSnapshot对象永远不会为null,哪怕你查询的节点完全不存在。它只会通过exists()方法返回false来表示节点不存在,或者getValue()返回null表示节点存在但没有有效数据。你原来的dataSnapshotCars != null && dataSnapshotPlanes != null判断永远为true,所以自然只会弹出第一个Toast。
修正后的嵌套监听版本代码
如果暂时想保留你原来的嵌套结构,只需要把判断条件换成exists()方法:
mDatabase.child("Users").child(FirebaseAuth.getInstance().getCurrentUser().getUid()).child("URL_CARS").addValueEventListener(new ValueEventListener() { @Override public void onDataChange(final DataSnapshot dataSnapshotCars) { mDatabase.child("Users").child(FirebaseAuth.getInstance().getCurrentUser().getUid()).child("URL_PLANES").addValueEventListener(new ValueEventListener() { @Override public void onDataChange(DataSnapshot dataSnapshotPlanes) { // 改用exists()判断节点是否存在 if (dataSnapshotCars.exists() && dataSnapshotPlanes.exists()) { Toast.makeText(LoginActivity.this, "DATA EXISTS", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(LoginActivity.this, "Data DOESN'T EXISTS", Toast.LENGTH_SHORT).show(); } } @Override public void onCancelled(DatabaseError databaseError) { // 别忽略错误处理,方便排查问题 Toast.makeText(LoginActivity.this, "查询失败: " + databaseError.getMessage(), Toast.LENGTH_SHORT).show(); } }); } @Override public void onCancelled(DatabaseError databaseError) { Toast.makeText(LoginActivity.this, "查询失败: " + databaseError.getMessage(), Toast.LENGTH_SHORT).show(); } });
更优写法:单次查询获取两个节点
嵌套监听会发起两次数据库请求,其实我们可以一次性查询当前用户节点下的所有数据,再判断两个子节点的状态,这样更高效也更简洁:
mDatabase.child("Users").child(FirebaseAuth.getInstance().getCurrentUser().getUid()) .addValueEventListener(new ValueEventListener() { @Override public void onDataChange(DataSnapshot userSnapshot) { // 直接从用户快照中获取两个子节点的状态 boolean hasCarsData = userSnapshot.child("URL_CARS").exists(); boolean hasPlanesData = userSnapshot.child("URL_PLANES").exists(); if (hasCarsData && hasPlanesData) { Toast.makeText(LoginActivity.this, "DATA EXISTS", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(LoginActivity.this, "Data DOESN'T EXISTS", Toast.LENGTH_SHORT).show(); } } @Override public void onCancelled(DatabaseError databaseError) { Toast.makeText(LoginActivity.this, "数据库查询失败: " + databaseError.getMessage(), Toast.LENGTH_SHORT).show(); } });
额外补充:判断节点是否有非空有效数据
如果你的业务逻辑要求节点不仅存在,还要有有效的URL内容(比如不能是空字符串),可以进一步判断getValue()的结果:
String carsUrl = userSnapshot.child("URL_CARS").getValue(String.class); String planesUrl = userSnapshot.child("URL_PLANES").getValue(String.class); // 检查两个URL都不为null且非空 if (carsUrl != null && !carsUrl.trim().isEmpty() && planesUrl != null && !planesUrl.trim().isEmpty()) { Toast.makeText(LoginActivity.this, "有效数据已存在", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(LoginActivity.this, "数据不存在或为空", Toast.LENGTH_SHORT).show(); }
内容的提问来源于stack exchange,提问作者Gastón Saillán
相关产品推荐
相关产品推荐

