Android中基于RegId从Firebase实时数据库更新数据失败问题
Firebase实时数据库更新失败问题排查与修复
我需要基于用户保存的RegId(作为子字符串存储,而非通过Auth认证)从Firebase实时数据库检索数据并更新对应值,但当前编写的updateDatatoFirebase方法无法完成更新操作。
当前更新数据代码
private void updateDatatoFirebase(String regid, String doctor_name, String city,String speciality) { Map<String, Object> update=new HashMap<>(); update.put("doctor",doctor_name); update.put("city",city); update.put("speciality",speciality); DatabaseReference dbref=FirebaseDatabase.getInstance().getReference(); dbref.addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot snapshot) { for (DataSnapshot ds : snapshot.getChildren()){ key = snapshot.getKey(); if(checkid.equalsIgnoreCase(regid)) { dbref.updateChildren(update); Toast.makeText(need_help.this, "Data in Database updated", Toast.LENGTH_SHORT).show(); } else Toast.makeText(need_help.this, "No such id found", Toast.LENGTH_SHORT).show(); } } @Override public void onCancelled(@NonNull DatabaseError error) { Toast.makeText(need_help.this, "Fail to add data " + error, Toast.LENGTH_SHORT).show(); } }); }
数据添加代码
private void addDatatoFirebase(String regid, String doctor_name, String city,String speciality) { root=firebaseDatabase.getReference().child("RegId").child(regid); HashMap<String, String> usermap=new HashMap<>(); usermap.put("doctor",doctor_name); usermap.put("city",city); usermap.put("speciality",speciality); root.addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot snapshot) { root.push().setValue(usermap); Toast.makeText(need_help.this, "Data in Database updated", Toast.LENGTH_SHORT).show(); } @Override public void onCancelled(@NonNull DatabaseError error) { Toast.makeText(need_help.this, "Fail to add data " + error, Toast.LENGTH_SHORT).show(); } }); }
问题分析
- 根引用定位错误:更新方法直接使用数据库根节点,而数据实际存储在
RegId/regid/随机pushId路径下,未定位到正确子节点。 - 循环逻辑错误:循环中错误获取根节点key而非当前子节点
ds的key;checkid变量未定义,缺少RegId匹配逻辑。 - 更新路径错误:调用
dbref.updateChildren(update)会更新根节点字段,而非目标子节点,导致数据更新到错误位置。 - 添加数据冗余:添加时无需监听快照即可调用
push(),且push()生成的随机ID会让每个RegId下存在多个子节点,增加更新复杂度。
修复方案
优化添加数据方法(可选,简化结构)
若每个RegId仅需存储一条数据,可移除push(),直接写入RegId节点:
private void addDatatoFirebase(String regid, String doctor_name, String city,String speciality) { DatabaseReference root = FirebaseDatabase.getInstance().getReference().child("RegId").child(regid); HashMap<String, String> usermap = new HashMap<>(); usermap.put("doctor", doctor_name); usermap.put("city", city); usermap.put("speciality", speciality); root.setValue(usermap) .addOnSuccessListener(aVoid -> Toast.makeText(need_help.this, "Data added successfully", Toast.LENGTH_SHORT).show()) .addOnFailureListener(e -> Toast.makeText(need_help.this, "Failed to add data: " + e.getMessage(), Toast.LENGTH_SHORT).show()); }
修复更新数据方法
场景1:每个RegId对应一条数据(无随机pushId)
直接通过路径定位目标节点并更新:
private void updateDatatoFirebase(String regid, String doctor_name, String city,String speciality) { Map<String, Object> update = new HashMap<>(); update.put("doctor", doctor_name); update.put("city", city); update.put("speciality", speciality); DatabaseReference targetRef = FirebaseDatabase.getInstance().getReference() .child("RegId").child(regid); targetRef.updateChildren(update) .addOnSuccessListener(aVoid -> Toast.makeText(need_help.this, "Data updated successfully", Toast.LENGTH_SHORT).show()) .addOnFailureListener(e -> Toast.makeText(need_help.this, "Update failed: " + e.getMessage(), Toast.LENGTH_SHORT).show()); }
场景2:每个RegId下有多个随机pushId子节点
遍历RegId下的子节点,找到匹配项后更新:
private void updateDatatoFirebase(String regid, String doctor_name, String city,String speciality) { Map<String, Object> update = new HashMap<>(); update.put("doctor", doctor_name); update.put("city", city); update.put("speciality", speciality); DatabaseReference regIdRef = FirebaseDatabase.getInstance().getReference().child("RegId").child(regid); regIdRef.addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot snapshot) { boolean found = false; for (DataSnapshot ds : snapshot.getChildren()) { // 根据实际数据结构调整匹配逻辑,比如从子节点获取regid字段 String childRegId = ds.getKey(); if (regid.equalsIgnoreCase(childRegId)) { ds.getRef().updateChildren(update); Toast.makeText(need_help.this, "Data updated", Toast.LENGTH_SHORT).show(); found = true; break; } } if (!found) { Toast.makeText(need_help.this, "No such id found", Toast.LENGTH_SHORT).show(); } } @Override public void onCancelled(@NonNull DatabaseError error) { Toast.makeText(need_help.this, "Update failed: " + error.getMessage(), Toast.LENGTH_SHORT).show(); } }); }
内容的提问来源于stack exchange,提问作者Raunak Seth
相关产品推荐
相关产品推荐

