我为每个具有privacy
字段的用户提供了项目(请参阅下面的结构)。我需要使用规则,允许所有者用户阅读他的所有项目,但另一个用户只能阅读隐私项目> 0(0表示私人物品)。所以请帮我创建这个规则。
我当前的规则不起作用,因为它不允许在我的Android应用中使用getReference("items/{userUid}").addChildEventListener
来阅读用户的项目。
root
items
{userUid}
{itemUid}
name: a
privacy: 0
{itemUid}
name: b
privacy: 1
规则:
"items": {
"$uid": {
"$itemUid": {
".read": "$uid === auth.uid || data.child('privacy').val() > 0"
},
".write": "auth != null && $uid === auth.uid"
}
}
答案 0 :(得分:1)
您说您尝试阅读items/{userUid}
,但您的规则设置为items/{userUid}/{itemUid}
。您应该移除那个更深的孩子,并将您的阅读规则保持在{userUid}
:
"items": {
"$uid": {
".read": "$uid === auth.uid || data.child('privacy').val() > 0",
".write": "auth != null && $uid === auth.uid"
}
}
更新1:请记住rules are not filters。这意味着用户可以从该节点读取所有数据,或者根本不读取任何数据。但是,使用recently introduced Query-based rules可以解决您的问题。
您可以将您正在使用的查询保留为阅读所有者数据:
getReference("items/{userUid}").addChildEventListener
但是当为其他用户读取数据时,您需要对其进行过滤以仅显示privacy>0
的
getReference("items/{userUid}").orderByChild('privacy').startAt(1).addChildEventListener
(orderByChild('privacy').startAt(1)
相当于privacy>=1
)
然后,您可以将此查询添加到规则中,以确保仅在使用此查询时才读取此数据:
{
"rules": {
"items": {
"$uid": {
".read": "$uid == auth.uid || (query.orderByChild === 'privacy' && query.startAt === 1)",
".write": "auth != null && $uid === auth.uid",
".indexOn":["privacy"]
}
}
}
}
请注意,在按隐私排序数据时,我还向improve performance添加了.indexOn
。
更新2:要直接访问项目,您可以使用以下规则:
".read": "(auth != null && $uid === auth.uid) || (auth != null && query.orderByKey) || (auth != null && query.orderByChild === 'privacy' && query.startAt === '1')"
并使用以下方式访问它:
getReference(ref_to_items_userUid).orderByKey().equalTo(itemKey)