Flutter & Firebase双字段排序:按存储位置再按物品名称排序
问题描述
开发类购物清单应用,当前使用Firebase的orderBy方法实现单字段排序。现有数据包含itemName、itemStorage、itemNumber三个字段,示例数据如下:
| itemName | itemStorage | itemNumber |
|---|---|---|
| Tomatoes | pantry | 2 |
| Potatoes | pantry | 5 |
| Salmon | freezer | 2 |
| Beer | pantry | 5 |
| Onion | pantry | 3 |
| Pizza | freezer | 2 |
期望实现先按itemStorage排序,再按itemName排序的效果,排序后结果如下:
| itemName | itemStorage | itemNumber |
|---|---|---|
| Beer | pantry | 5 |
| Onion | pantry | 3 |
| Potatoes | pantry | 5 |
| Tomatoes | pantry | 2 |
| Pizza | freezer | 2 |
| Salmon | freezer | 2 |
当前获取数据的代码片段:
... child: StreamBuilder<QuerySnapshot>( stream: fireStore.collection('items').orderBy("itemName").snapshots(), builder: (context, snapshot) { if (!snapshot.hasData) { return const Text('No tasks to display'); } else { return ListView( children: snapshot.data!.docs.map((DocumentSnapshot document) { Map<String, dynamic> data = document.data()! as Map<String, dynamic>; ... ... }
解决方案
1. 链式调用orderBy实现多字段排序
Firebase Firestore支持通过链式调用多个orderBy方法实现多优先级排序,排序优先级由调用顺序决定:先调用的字段为第一排序条件,后调用的为第二条件。
修改后的stream部分代码如下:
stream: fireStore.collection('items') .orderBy("itemStorage") .orderBy("itemName") .snapshots(),
2. 创建复合索引
使用多字段排序时,Firebase要求必须创建对应的复合索引,否则会抛出权限/索引缺失的错误。创建步骤:
- 打开Firebase控制台,进入Firestore数据库页面
- 切换到「索引」标签页,点击「添加索引」
- 选择
items集合,添加字段itemStorage(排序方式选「升序」)、itemName(排序方式选「升序」) - 点击「创建索引」,等待索引构建完成(通常需要几分钟)
3. 验证结果
修改代码并创建索引后,Stream获取的数据会先按itemStorage分组排序,同一分组内的条目再按itemName字母顺序排序,完全符合期望结果。
内容的提问来源于stack exchange,提问作者Luca
相关产品推荐
相关产品推荐

