You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用addChildEventListener结合orderByChild排序数据失效问题

Firebase Realtime Database 排序不生效问题解决

问题背景

在Firebase Realtime Database中,根节点下的Board0节点包含BoardContent子节点,该子节点下有多个子元素,每个子元素包含三个键值对。尝试使用orderByChild("xxx")结合addChildEventListener对BoardContent的数据进行排序,但返回结果未按预期排序。因addValueEventListener在数据修改时会返回整个数据集,影响性能,故不考虑使用该方法。最初尝试按timestamp字段排序无效,新增xxx字段后问题依旧。

数据库示例数据

{
  "Board0": {
    "BoardContent": {
      "Entity:-NHnf7hxqp5W-Pb7-YtL": {
        "-NHnf7hxqp5W-Pb7-YtL": "rO0ABXNyAB1kcmF3aW5nTW9kZWxEYXRhLlBlbmNpbEVudGl0eVAZLREIo9RXAgAAeHIAFGRyYXdpbmdNb2RlbERhdGEuUGVuA0PYb7ApjnsCAAdJAAtzdHJva2VDb2xvckkAC3N0cm9rZVdpZHRoTAALZmlyZWJhc2VLZXl0ABJMamF2YS9sYW5nL1N0cmluZztMABFsaW5lVG9Db29yZGluYXRlc3QAFUxqYXZhL3V0aWwvQXJyYXlMaXN0O0wAEW1vdmVUb0Nvb3JkaW5hdGVzcQB+AANMABFxdWFkVG9Db29yZGluYXRlc3EAfgADTAAJdGltZVN0YW1wdAAPTGphdmEvdXRpbC9NYXA7eHD/hISEAAAABXQAFC1OSG5mN2h4cXA1Vy1QYjctWXRMc3IAE2phdmEudXRpbC5BcnJheUxpc3R4gdIdmcdhnQMAAUkABHNpemV4cAAAAAJ3BAAAAAJzcgAPamF2YS5sYW5nLkZsb2F02u3Jots88OwCAAFGAAV2YWx1ZXhyABBqYXZhLmxhbmcuTnVtYmVyhqyVHQuU4IsCAAB4cENb9+BzcQB+AAlD+4oYeHNxAH4ABwAAAAJ3BAAAAAJzcQB+AAlDWPgQc3EAfgAJQ3LuAHhzcQB+AAcAAAA8dwQAAAA8c3EAfgAJQ1j4EHNxAH4ACUNy7gBzcQB+AAlDWPgQc3EAfgAJQ3Yz7XNxAH4ACUNY+BBzcQB+AAlDeXnac3EAfgAJQ1j4EHNxAH4ACUN9K99zcQB+AAlDWPgQc3EAfgAJQ4Bu8nNxAH4ACUNY+BBzcQB+AAlDggGec3EAfgAJQ1j4EHNxAH4ACUODlElzcQB+AAlDWPgQc3EAfgAJQ4YFOHNxAH4ACUNY+BBzcQB+AAlDiHYnc3EAfgAJQ1kyGHNxAH4ACUOb/UhzcQB+AAlDWWwfc3EAfgAJQ6+EaHNxAH4ACUNbS9NzcQB+AAlDtBm3c3EAfgAJQ10rh3NxAH4ACUO4rwZzcQB+AAlDXhGcc3EAfgAJQ70FjHNxAH4ACUNe97BzcQB+AAlDwVwSc3EAfgAJQ173sHNxAH4ACUPHk+FzcQB+AAlDXvewc3EAfgAJQ83LsHNxAH4ACUNe97BzcQB+AAlD1mzXc3EAfgAJQ173sHNxAH4ACUPfDf5zcQB+AAlDXvewc3EAfgAJQ+DzdHNxAH4ACUNe97BzcQB+AAlD4tjqc3EAfgAJQ173sHNxAH4ACUPni7BzcQB+AAlDXvewc3EAfgAJQ+w+dnNxAH4ACUNdxAtzcQB+AAlD7jU9c3EAfgAJQ1yQZnNxAH4ACUPwLARzcQB+AAlDXEQjc3EAfgAJQ/KiQHNxAH4ACUNb9+BzcQB+AAlD9Rh8c3EAfgAJQ1v34HNxAH4ACUP3N0ZzcQB+AAlDW/fgc3EAfgAJQ/lWEHNxAH4ACUNb9+BzcQB+AAlD+nAUeHA=",
        "timestamp": 1669461742110,
        "xxx": 2
      },
      "Entity:-NHnf86gFAkcyWLnTXkt": {
        "-NHnf86gFAkcyWLnTXkt": "rO0ABXNyAB1kcmF3aW5nTW9kZWxEYXRhLlBlbmNpbEVudGl0eVAZLREIo9RXAgAAeHIAFGRyYXdpbmdNb2RlbERhdGEuUGVuA0PYb7ApjnsCAAdJAAtzdHJva2VDb2xvckkAC3N0cm9rZVdpZHRoTAALZmlyZWJhc2VLZXl0ABJMamF2YS9sYW5nL1N0cmluZztMABFsaW5lVG9Db29yZGluYXRlc3QAFUxqYXZhL3V0aWwvQXJyYXlMaXN0O0wAEW1vdmVUb0Nvb3JkaW5hdGVzcQB+AANMABFxdWFkVG9Db29yZGluYXRlc3EAfgADTAAJdGltZVN0YW1wdAAPTGphdmEvdXRpbC9NYXA7eHD/hISEAAAABXQAFC1OSG5mODZnRkFrY3lXTG5UWGt0c3IAE2phdmEudXRpbC5BcnJheUxpc3R4gdIdmcdhnQMAAUkABHNpemV4cAAAAAJ3BAAAAAJzcgAPamF2YS5sYW5nLkZsb2F02u3Jots88OwCAAFGAAV2YWx1ZXhyABBqYXZhLmxhbmcuTnVtYmVyhqyVHQuU4IsCAAB4cEPYfbhzcQB+AAlD8W82eHNxAH4ABwAAAAJ3BAAAAAJzcQB+AAlDx/qIc3EAfgAJQ17zAHhzcQB+AAcAAAAcdwQAAAAcc3EAfgAJQ8f6iHNxAH4ACUNe8wBzcQB+AAlDx/qIc3EAfgAJQ2x0inNxAH4ACUPH+ohzcQB+AAlDefYUc3EAfgAJQ8j74HNxAH4ACUOBP1ZzcQB+AAlDyf04c3EAfgAJQ4WDoXNxAH4ACUPKrnFzcQB+AAlDh3Gac3EAfgAJQ8tfqnNxAH4ACUOJX5JzcQB+AAlDzS2Vc3EAfgAJQ4/wrHNxAH4ACUPO+4BzcQB+AAlDloHFc3EAfgAJQ9DQsHNxAH4ACUOiRPZzcQB+AAlD0qXfc3EAfgAJQ64IJnNxAH4ACUPUEeRzcQB+AAlDuw2Rc3EAfgAJQ9V96HNxAH4ACUPIEvxzcQB+AAlD1v3Qc3EAfgAJQ9zBGXhw",
        "timestamp": 1669461742689,
        "xxx": 3
      },
      "Entity:-NHnf8LbmkautY7DNu_k": {
        "-NHnf8LbmkautY7DNu_k": "rO0ABXNyAB1kcmF3aW5nTW9kZWxEYXRhLlBlbmNpbEVudGl0eVAZLREIo9RXAgAAeHIAFGRyYXdpbmdNb2RlbERhdGEuUGVuA0PYb7ApjnsCAAdJAAtzdHJva2VDb2xvckkAC3N0cm9rZVdpZHRoTAALZmlyZWJhc2VLZXl0ABJMamF2YS9sYW5nL1N0cmluZztMABFsaW5lVG9Db29yZGluYXRlc3QAFUxqYXZhL3V0aWwvQXJyYXlMaXN0O0wAEW1vdmVUb0Nvb3JkaW5hdGVzcQB+AANMABFxdWFkVG9Db29yZGluYXRlc3EAfgADTAAJdGltZVN0YW1wdAAPTGphdmEvdXRpbC9NYXA7eHD/hISEAAAABXQAFC1OSG5mOExibWthdXRZN0ROdV9rc3IAE2phdmEudXRpbC5BcnJheUxpc3R4gdIdmcdhnQMAAUkABHNpemV4cAAAAAJ3BAAAAAJzcgAPamF2YS5sYW5nLkZsb2F02u3Jots88OwCAAFGAAV2YWx1ZXhyABBqYXZhLmxhbmcuTnVtYmVyhqyVHQuU4IsCAAB4cERDPaRzcQB+AAlEQ3vAeHNxAH4ABwAAAAJ3BAAAAAJzcQB+AAlEG71Mc3EAfgAJQuvmAHhzcQB+AAcAAAAkdwQAAAAkc3EAfgAJRBu9THNxAH4ACULr5gBzcQB+AAlEHNZUc3EAfgAJQxR+5nNxAH4ACUQd71tzcQB+AAlDMwrMc3EAfgAJRCIkf3NxAH4ACUOESQBzcQB+AAlEJlmjc3EAfgAJQ68MmnNxAH4ACUQqv+JzcQB+AAlD2Q1Uc3EAfgAJRC8mInNxAH4ACUQBhwdzcQB+AAlEM/Hmc3EAfgAJRBC2hnNxAH4ACUQ4valzcQB+AAlEH+YFc3EAfgAJRDyr8nNxAH4ACUQqcDxzcQB+AAlEQJo6c3EAfgAJRDT6c3NxAH4ACURB6+9zcQB+AAlEN6Boc3EAfgAJREM9pHNxAH4ACUQ6Rl5zcQB+AAlEQ52ec3EAfgAJRDx7FXNxAH4ACURD/ZhzcQB+AAlEPq/Mc3EAfgAJREP9mHNxAH4ACURACgxzcQB+AAlEQ/2Yc3EAfgAJREFkTXNxAH4ACURDnZ5zcQB+AAlEQnAGeHA=",
        "timestamp": 1669461743632,
        "xxx": 5
      },
      "Entity:-NHnf8cbA4yiBmPyFsu2": {
        "-NHnf8cbA4yiBmPyFsu2": "rO0ABXNyAB1kcmF3aW5nTW9kZWxEYXRhLlBlbmNpbEVudGl0eVAZLREIo9RXAgAAeHIAFGRyYXdpbmdNb2RlbERhdGEuUGVuA0PYb7ApjnsCAAdJAAtzdHJva2VDb2xvckkAC3N0cm9rZVdpZHRoTAALZmlyZWJhc2VLZXl0ABJMamF2YS9sYW5nL1N0cmluZztMABFsaW5lVG9Db29yZGluYXRlc3QAFUxqYXZhL3V0aWwvQXJyYXlMaXN0O0wAEW1vdmVUb0Nvb3JkaW5hdGVzcQB+AANMABFxdWFkVG9Db29yZGluYXRlc3EAfgADTAAJdGltZVN0YW1wdAAPTGphdmEvdXRpbC9NYXA7eHD/hISEAAAABXQAFC1OSG5mOGNiQTR5aUJtUHlGc3Uyc3IAE2phdmEudXRpbC5BcnJheUxpc3R4gdIdmcdhnQMAAUkABHNpemV4cAAAAAJ3BAAAAAJzcgAPamF2YS5sYW5nLkZsb2F02u3Jots88OwCAAFGAAV2YWx1ZXhyABBqYXZhLmxhbmcuTnVtYmVyhqyVHQuU4IsCAAB4cERqfJhzcQB+AAlELfhreHNxAH4ABwAAAAJ3BAAAAAJzcQB+AAlEVrxsc3EAfgAJQh/YAHhzcQB+AAcAAAAcdwQAAAAcc3EAfgAJRFa8bHNxAH4ACUIf2ABzcQB+AAlEVrxsc3EAfgAJQoKhDnNxAH4ACURWvGxzcQB+AAlCtVYcc3EAfgAJRFjBqnNxAH4ACUMscWtzcQB+AAlEWsboc3EAfgAJQ343yHNxAH4ACURco3RzcQB+AAlDrGcWc3EAfgAJRF6AAHNxAH4ACUPZskhzcQB+AAlEYN+oc3EAfgAJQ/T39HNxAH4ACURjP1BzcQB+AAlECB7Qc3EAfgAJRGRUdnNxAH4ACUQQ2tBzcQB+AAlEZWmcc3EAfgAJRBmW0XNxAH4ACURnWQ5zcQB+AAlEIePmc3EAfgAJRGlIgHNxAH4ACUQqMPxzcQB+AAlEaeKMc3EAfgAJRCwUtHhw",
        "timestamp": 1669461744949,
        "xxx": 1
      }
    }
  }
}

原代码片段

FirebaseDatabase board0ContentReference = firebaseDatabase.getReference().child("Board0").child("BoardContent");

board0ContentReference.orderByChild("xxx").addChildEventListener(new ChildEventListener() {
  @Override
  public void onChildAdded(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) {
      DataSnapshot snapshotChild =  snapshot.getChildren().iterator().next(); // 获取第一个子项

      System.out.println("Item Key: " + snapshotChild.getKey());   
  }

  @Override
  public void onChildChanged(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) {
  }

  @Override
  public void onChildRemoved(@NonNull DataSnapshot snapshot) {
  }

  @Override
  public void onChildMoved(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) {
  }

  @Override
  public void onCancelled(@NonNull DatabaseError error) {
  }
});

问题原因

Firebase的orderByChild("xxx")已经正确对BoardContent下的所有Entity:-xxx节点按xxx字段排序,每个onChildAdded回调中的snapshot对应的就是一个排序后的Entity:-xxx节点。但原代码中错误地获取了snapshot的第一个子节点的key(即每个Entity节点内部的长字符串key),而不是当前snapshot自身的key(也就是Entity:-xxx)。这导致打印的key并非排序后的父节点key,所以看起来排序没生效。

解决方案

修改onChildAdded方法,直接使用snapshot.getKey()获取当前节点的key,无需遍历子节点:

@Override
public void onChildAdded(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) {
    System.out.println("Item Key: " + snapshot.getKey());   
}

验证结果

修改后,控制台将输出预期的排序结果:

Item Key: Entity:-NHnf8cbA4yiBmPyFsu2
Item Key: Entity:-NHnf7hxqp5W-Pb7-YtL
Item Key: Entity:-NHnf86gFAkcyWLnTXkt
Item Key: Entity:-NHnf8LbmkautY7DNu_k

内容的提问来源于stack exchange,提问作者osama zaza

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 23:50:28