Flutter:Firebase 实时数据库 orderByChild 对查询结果没有影响

Posted

技术标签:

【中文标题】Flutter:Firebase 实时数据库 orderByChild 对查询结果没有影响【英文标题】:Flutter: Firebase Real-Time database orderByChild has no impact on query result 【发布时间】: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

【问题讨论】:

【参考方案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 中的计数器,也可以监听整个值。 你能举一个监听整个值的例子吗?这样一来,一切都会按顺序排列吗?非常感谢!

以上是关于Flutter:Firebase 实时数据库 orderByChild 对查询结果没有影响的主要内容,如果未能解决你的问题,请参考以下文章

使用 Firebase 实时数据库 Flutter 进行实时更新

Flutter:Firebase 实时数据库 orderByChild 对查询结果没有影响

如何从 Firebase 实时数据库中获取数据到 Flutter 中的列表中?

如何使用 Flutter 和 Firebase 实时数据库实现邀请系统 [关闭]

使用flutter如何在同一个App中使用多个firebase实时数据库

如何在flutter中从firebase实时数据库中获取数据?