【问题标题】:Flutter: Firebase Real-Time database orderByChild has no impact on query resultFlutter:Firebase 实时数据库 orderByChild 对查询结果没有影响
【发布时间】:2020-08-03 14:08:17
【问题描述】:

我已经像这样将这样的数据插入到 Firebase 实时数据库中:

我这样查询数据库:

final databaseReference = FirebaseDatabase.instance.reference();
databaseReference
    .child('orders')
    .orderByChild('date_slug')
    .limitToFirst(pageSize)
    .once()
    .then((snapshot) {
  firstPageItems = snapshot.value;

  if (firstPageItems != null) {
    List<dynamic> curretList = [];
    firstPageItems.forEach((orderId, orderData) {

      print ("date_slug " + orderData['date_slug'] + "\r\n\r\n\r\n");
      curretList.add(orderData);
    });

    _list.addAll(curretList);
    _listController.sink.add(_list);
  }
});

但是,返回的数据并没有像我预期的那样排序。请参阅下面的输出。

I/flutter (17125): date_slug 2020-04-20 15:52:13
I/flutter (17125): 
I/flutter (17125): 
I/flutter (17125): date_slug 2020-04-20 15:52:11
I/flutter (17125): 
I/flutter (17125): 
I/flutter (17125): date_slug 2020-04-20 15:52:10
I/flutter (17125): 
I/flutter (17125): 
I/flutter (17125): date_slug 2020-04-20 15:52:12

【问题讨论】:

    标签: firebase flutter firebase-realtime-database


    【解决方案1】:

    只要您致电firstPageItems = snapshot.value,您就会将结果转换为地图/字典。字典可以保存结果的键和值,但它不存在结果的相对顺序。

    为了保持结果的顺序,您需要观察onChildAdded

    var query = databaseReference
        .child('orders')
        .orderByChild('date_slug')
        .limitToFirst(pageSize);
    query.onChildAdded
        .forEach((event) => {
          print(event.snapshot.value)
        });
    

    如果您需要知道查询的所有子节点何时已被处理,您可以为 value 事件添加一个额外的侦听器:

    query.once().then((snapshot) {
      print("Done loading all data for query");
    });
    

    添加这个额外的侦听器不会导致下载额外的数据,因为 Firebase 会在后台进行重复数据删除。


    或者,您可以使用 FlutterFire 库中的 FirebaseList class,它使用相同的 onChildAdded 和其他 onChild... 流来维护索引列表。

    使用这个类的一个例子:

    list = FirebaseList(query: query, 
      onChildAdded: (pos, snapshot) {},
      onChildRemoved: (pos, snapshot) {},
      onChildChanged: (pos, snapshot) {},
      onChildMoved: (oldpos, newpos, snapshot) {},
      onValue: (snapshot) {
        for (var i=0; i < this.list.length; i++) {
          print('$i: ${list[i].value}');
        }
      }
    );
    

    如您所见,这使用列表的onValue 流按顺序循环遍历子项。 FirebaseList 类需要 onChild... 方法,但我们在这里没有对它们做任何有意义的事情。


    在最新版本的 FlutterFire 库中,DataSnapshot 类现在具有 children 属性,这意味着您终于可以这样做了:

    query.onValue((event) {
      event.snapshot.children.forEach((child) {
        print(child.value);
      });
    })
    

    【讨论】:

    • 这行得通,但我怎么知道这个查询返回了多少项目?
    • 您无法确定onChildAdded 中的结果总数。您可以继续增加 onChildAdded 中的计数器,也可以监听整个值。
    • 你能举一个监听整个值的例子吗?这样一来,一切都会按顺序排列吗?非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-22
    • 1970-01-01
    • 2020-04-25
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    相关资源
    最近更新 更多