Android开发中如何获取Firebase Realtime Database特定子节点的键值
Android开发Firebase Realtime Database按科目名查询对应键值实现方案
问题根因
你当前代码返回空值的核心原因是Firebase Realtime Database的读取操作为异步执行:addChildEventListener添加完成后不会立刻触发onChildAdded回调,主线程会直接向下执行列表遍历逻辑,此时subjectNamesList还未被赋值,自然无法匹配到结果返回空值。
另外你当前全量拉取所有科目再遍历匹配的逻辑也不合理,科目数量较多时会浪费带宽和性能,直接用Firebase的查询过滤能力即可直接定位目标节点。
正确实现方案
1. 先定义异步回调接口
因为异步操作无法直接通过return返回结果,需要用回调接收查询结果:
public interface SubjectUuidCallback { // 查询成功回调,uuid为匹配到的结果,无匹配时为null void onUuidLoaded(String uuid); // 查询失败回调 void onQueryError(DatabaseError error); }
2. 按科目名查询的方法实现
public void getSubjectUuid(String selectedSubject, SubjectUuidCallback callback) { DatabaseReference addedSubjectRef = FirebaseDatabase .getInstance() .getReference(classCreatorPhoneNo + "/class_list/" + classUuid + "/added_subject"); // 直接按subject_name字段过滤,不需要拉取全量数据 addedSubjectRef.orderByChild("subject_name").equalTo(selectedSubject) .addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot snapshot) { if (snapshot.exists()) { // 遍历查询结果,正常只会有一个匹配节点 for (DataSnapshot subjectSnap : snapshot.getChildren()) { // 如需获取截图中蓝框标注的节点本身的键,替换为subjectSnap.getKey()即可 String targetUuid = subjectSnap.child("subject_uuid").getValue(String.class); callback.onUuidLoaded(targetUuid); return; } } // 无匹配科目 callback.onUuidLoaded(null); } @Override public void onCancelled(@NonNull DatabaseError error) { callback.onQueryError(error); } }); }
3. 方法调用示例
// 传入用户选择的科目名,在回调中处理结果 getSubjectUuid(selectedSubject, new SubjectUuidCallback() { @Override public void onUuidLoaded(String uuid) { if (uuid != null) { // 此处为拿到结果后的业务逻辑,比如给classKey赋值 classKey = uuid; // 后续逻辑必须写在这里,不能写在getSubjectUuid方法调用之后 } else { // 无匹配科目提示逻辑 } } @Override public void onQueryError(DatabaseError error) { // 数据库查询错误处理逻辑 } });
参考数据库结构

内容的提问来源于stack exchange,提问作者Vinayak Sutar
相关产品推荐
相关产品推荐

