FlutterFire中为何无法同时使用where()与orderBy()方法?
Firestore同时使用whereNotIn与orderBy时的断言错误解决办法
问题场景
在Widget中通过StreamBuilder查询Firestore数据,同时使用whereNotIn过滤条件和orderBy排序时,触发了断言错误:
原查询代码
child: StreamBuilder( stream: FirebaseFirestore.instance .collection("users") .doc(currenUserUid) .collection("chat") .where('modlerUid', whereNotIn: _user.blockedList) .orderBy("time", descending: true) .snapshots(),
错误信息
Exception has occurred.
_AssertionError ('package:cloud_firestore/src/query.dart': Failed assertion: line 489 pos 13: 'conditionField == orders[0][0]': The initial orderBy() field "[[FieldPath([time]), true]][0][0]" has to be the same as the where() field parameter "FieldPath([modlerUid])" when an inequality operator is invoked.)
解决办法
Firestore规则明确:使用whereNotIn这类不等操作符时,必须将where条件对应的字段作为第一个排序字段,之后才能添加其他排序规则。
方案一:调整查询排序顺序
修改查询语句,先按modlerUid排序,再按time倒序:
child: StreamBuilder( stream: FirebaseFirestore.instance .collection("users") .doc(currenUserUid) .collection("chat") .where('modlerUid', whereNotIn: _user.blockedList) .orderBy("modlerUid") // 优先按where条件字段排序 .orderBy("time", descending: true) // 再按时间倒序 .snapshots(),
这种方式会先按modlerUid的字符串顺序分组,同组内的聊天记录按时间倒序排列。
方案二:客户端二次排序
如果需要完全按时间倒序展示,不受modlerUid排序影响,可以在获取Firestore快照后,在客户端对数据二次排序:
builder: (context, snapshot) { if (snapshot.hasData && snapshot.data!.docs.isNotEmpty) { // 将查询结果转为列表并按time倒序排序 final chatDocs = snapshot.data!.docs.toList() ..sort((a, b) => b['time'].compareTo(a['time'])); return ListView.builder( itemCount: chatDocs.length, itemBuilder: (context, index) { final chatData = chatDocs[index].data(); // 构建你的聊天列表项 return ListTile( title: Text(chatData['xxx']), subtitle: Text(chatData['time'].toString()), ); }, ); } return snapshot.hasError ? Text('加载失败') : CircularProgressIndicator(); }
内容的提问来源于stack exchange,提问作者Dananjaya Fernando
相关产品推荐
相关产品推荐

