Ionic 3 Angularfire2:不改数据库结构获取pending状态订单
问题:在Ionic中从Firebase嵌套结构获取所有pending状态的订单
你的Firebase数据结构
{ "orders": { "user001": { "11168128": { "name": "order 1", "status": "pending" }, "11168129": { "name": "order 2", "status": "canceled" } }, "user002": { "11168130": { "name": "order 3", "status": "pending" } }, "user003": { "11168131": { "name": "order 4", "status": "pending" }, "11168132": { "name": "order 5", "status": "canceled" } } } }
你当前的错误查询代码
this.orders = this.db.list(`orders`, ref => ref.orderByChild('status').equalTo('pending')) .snapshotChanges().map(changes => { return changes.map(c => ({ key: c.payload.key, ...c.payload.val() })); });
问题原因
你现在的查询是直接在orders节点下找带有status字段的子节点,但orders的直接子节点是用户ID(比如user001),这些用户节点本身并没有status字段,status是在每个用户下的订单节点里。所以Firebase找不到符合条件的数据,自然返回错误结果。
解决方案(无需修改数据库结构)
我们需要先获取所有用户节点,再遍历每个用户下的订单,筛选出status为pending的订单。可以用RxJS的操作符来实现这个嵌套查询:
import { map, mergeMap } from 'rxjs/operators'; import { AngularFireList } from '@angular/fire/database'; // 修正后的查询代码 this.orders = this.db.list(`orders`).snapshotChanges().pipe( // 遍历每个用户节点,获取用户ID和该用户下的所有订单 mergeMap(userChanges => { return userChanges.map(userChange => { const userId = userChange.payload.key; const userOrders = userChange.payload.val() as { [key: string]: any }; // 将用户的订单转换成数组,同时带上用户ID和订单ID return Object.keys(userOrders).map(orderId => ({ userId: userId, orderId: orderId, ...userOrders[orderId] })); }); }), // 筛选出状态为pending的订单 filter(order => order.status === 'pending') );
代码解释
- 首先用
this.db.list('orders')获取所有用户节点的快照 mergeMap用来展开每个用户的订单数据,把嵌套结构转换成扁平的订单数组- 每个订单都会带上对应的
userId和orderId,方便后续业务处理 - 最后用
filter只保留status为pending的订单
这样就能得到所有用户下状态为pending的订单啦!
内容的提问来源于stack exchange,提问作者Azam Alvi
相关产品推荐
相关产品推荐

