如何让用户访问层次结构中某个节点以下的任何数据,并使其易于查询?这可以在Firebase中完成,还是我必须抛弃我心爱的Firebase并回到…抱怨…抱怨… RDBMS?
我尝试了两种不同的方式.一个可以轻松查询,但很难限制访问.另一个使得更容易限制访问,但意味着我必须做嵌套循环来聚合我的所有数据.
具体来说,我有一个典型的商业组织:
>公司
>西部地区
>第1分部
>部门1
>部门2
> 2区
>部门3
>部门4
>南部地区
>第3分部
>部门5
>部门6
>公司2
…等等.
在最低(部门)级别,我有订单的数量,我必须汇总.
第一次尝试
数据(非规范化)
{
"Orders": {
"UniqueID1": {
"company": "Company",
"region": "West Region",
"division": "Division 1",
"department": "Department 1",
"amount": 19.8
},
"UniqueID2": {
"company": "Company",
"region": "West Region",
"division": "Division 1",
"department": "Department 1",
"amount": 20.1
},
...and so on.
},
"Users": {
"Bob's UID": {
"departments": {
"Department 1": true, // Note that these two departments combined are Division 1
"Department 2": true
}
}
}
}
规则
{
"Orders": {
".indexOn": ["company", "region", "division", "department"],
".read":false,
".write":false,
"$order_id": {
".read": "root.child('Users').child(auth.uid).child('departments').hasChild(data.child('department').val())"
}
}
}
结论
优点
>查询是灵活的,例如:ordersRef.orderByChild(‘division’).equalTo(‘Division 1’).
>查询速度很快.对于200k记录,这在2秒内工作.
缺点
>我不相信我可以用一种结构来限制访问.我根据上面的规则得到permission_denied.我认为这是因为我遇到了“规则不是过滤器,tsk tsk tsk”的问题.
第二次尝试
数据(更加规范化)
{
"Orders": {
"Department 1": {
"UniqueID1": {
"company": "Company",
"region": "West Region",
"division": "Division 1",
"amount": 19.8
},
"UniqueID2": {
"company": "Company",
"region": "West Region",
"division": "Division 1",
"amount": 20.1
},
},
"Department 2": {...
...and so on.
},
"Users": {
"Bob's UID": {
"departments": {
"Department 1": true, // Note that these two departments combined are Division 1
"Department 2": true
}
}
}
}
规则
{
"Orders": {
".read":false,
".write":false,
"$order_id": {
".read": "root.child('Users').child(auth.uid).child('departments').hasChild(data.child('department').val())"
}
}
}
结论
优点
>我现在可以通过一次阅读一个部门来限制使用安全规则的访问权限.
缺点
>我认为我不能对“Orders / $order_id /”公司,地区或部门进行深度和变量索引,这意味着我必须单独调用每个部门的订单以在更高级别进行汇总.
最佳答案 您的第一个数据结构看似合理.您可以访问您有权访问的特定订单,并且您已经可以找到特定用户的部门列表.
要允许访问(例如)分部的订单,您还需要添加将分部映射到订单ID列表的二级索引:
{
"Orders": {
"UniqueID1": {
"company": "Company",
"region": "West Region",
"division": "Division 1",
"department": "Department 1",
"amount": 19.8
},
"UniqueID2": {
"company": "Company",
"region": "West Region",
"division": "Division 1",
"department": "Department 1",
"amount": 20.1
},
...and so on.
},
"Users": {
"Bob's UID": {
"departments": {
"Department 1": true, // Note that these two departments combined are Division 1
"Department 2": true
}
}
},
"OrdersByDivision": {
"Division 1": {
"UniqueID1": true,
"UniqueID2": true
}
}
}
现在,您可以在OrdersByDivision下找到带有方向查找的分部的订单列表,然后循环加载订单:
ref.child('OrdersByDivision/Division 1').on('child_added', function(snapshot) {
ref.child('Orders').child(snapshot.key).once('value', function(order) {
console.log(order.val());
});
});
大多数没有使用Firebase进行Web开发的开发人员担心这种模式会很慢.但鉴于Firebase通过已建立的连接检索项目,实际上这非常快.见Speed up fetching posts for my social network app by using query instead of observing a single event repeatedly