Firebase对象所有权与事件观察 [英] Firebase Object Ownership with Event Observation
问题描述
creatorId
属性,其值是经过身份验证的用户标识( authData.uid
使用Firebase身份验证对象)。我使用自定义令牌生成器进行身份验证,但问题可以通过匿名登录进行复制。 我希望用户只能读取(和写,但让我们专注于现在阅读,因为这是我有我的问题)他们创建的对象。换句话说,查询用户的认证用户ID将匹配它们所提取对象的 creatorId
。
I我在制作查询和规则时遇到了权限问题。
你缺少的是你假设安全规则是查询,这是不正确的。
检查
规则不是过滤部分链接。
安全规则只验证您是否可以读取或写入特定的Firebase路径数据库。
例如,如果您只想接收特定用户的更改,则应使用firebase查询。您想要获取特定用户的所有任务,您应该这样做:
let reference = Firebase(url:https: (creatorId)。queryEqualTo(YOUR_CURRENT_USER_UID).observeEventType(.ChildChanged,
withBlock:{(snapshot:FDataSnapshot!){// My-Firebase-Base-Reference} / tasks)
reference.queryOrderedByChild ) - >
中的无效$ // $成功
}){(错误:NSError!)在
中//错误:获取权限在此拒绝。
$ b这样你就可以得到所有与你的用户相关的事件,这些信息通过应用安全规则。如果你想只允许创建者写自己的任务,你也应该考虑创建任务和写入的情况像这样:
tasks:{
//您需要包含$ task_id否则规则会在任务中寻找creatorId子,而不是在自动生成的任务中
$ task_id:{
.read:auth.uid === data.child('creatorId')。val (),
//这是为了验证如果你正在创建一个任务,它必须在creatorId字段中有你自己的uid,并且你只能编辑你的任务...
。写:(newData.child('creatorId').val()=== auth.uid&&!data.exists())||(data.child('creatorId').val()= == auth.uid&& data.exists()),
//你应该加上th e index on告诉firebase这是一个查询索引,所以你的查询可以有效的,即使有大量的孩子
.indexOn:creatorId,
}
}
(检查语法,但这是一般想法)
I'm using Firebase in my iOS app. I'd like each of my objects to have a creatorId
property whose value is the authenticated user ID (authData.uid
with a Firebase authentication object). I'm using a custom token generator for authentication, but the problem can be reproduced with anonymous log in too.
I'd like a user to only be able to read (and write, but let's focus on reading right now, as that's where I'm having my issues) objects that they created. In other words, the querying user's authenticated user ID will match the creatorId
of the objects they are fetching.
I'm having trouble with permissions when I craft queries and rules to make this happen.
Here is the Firebase documentation for Rules and Security.
Here is what my Firebase dashboard looks like for a Task
object:
+ firebase-base
+ tasks
+ {task_id}
+ creatorId:
+ title:
where task_id
is a unique identifier generated by Firebase upon insertion.
My rules look like this (again, let's ignore writing rules for now):
{
"rules": {
"tasks": {
"$task_id": {
".read": "auth.uid === data.child('creatorId').val()"
}
}
}
}
Reading a specific task works fine, but I'd expect to be able to make a query that says, "fetch all the tasks that I created" using observeEventType
and related functions. This doesn't work for me. I get "Permission Denied" errors.
Here is how I'm observing, in Swift:
let reference = Firebase(url: "https://{My-Firebase-Base-Reference}/tasks")
reference.observeEventType(.ChildChanged,
withBlock: { (snapshot: FDataSnapshot!) -> Void in
// Success
}) { (error: NSError!) in
// Error: I get Permissions Denied here.
}
Per @Ymmanuel's suggestions, I also tried being more specific in my query, like so:
let reference = Firebase(url: "https://{My-Firebase-Base-Reference}/tasks")
reference.queryOrderedByChild("creatorId").queryEqualTo({USER_UID}).observeEventType(.ChildChanged,
withBlock: { (snapshot: FDataSnapshot!) -> Void in
// Success
}) { (error: NSError!) in
// Error: I get Permissions Denied here.
}
Neither of these blocks work, I always get "Permission Denied" errors. What am I doing wrong?
解决方案 What you are missing is that you are assuming that security rules are queries and that is not true.
Check the
Rules are Not Filters section in the link.
Security rules only validate if you can read or write a specific path of your firebase database.
If you want to only receive changes of a specific user you should use firebase queries.
For example if you want to get all the tasks of a specific user, you should do:
let reference = Firebase(url: "https://{My-Firebase-Base-Reference}/tasks")
reference.queryOrderedByChild("creatorId").queryEqualTo(YOUR_CURRENT_USER_UID).observeEventType(.ChildChanged,
withBlock: { (snapshot: FDataSnapshot!) -> Void in
// Success
}) { (error: NSError!) in
// Error: Get Permissions Denied Here.
}
This way you could get all the events only related to your user, and protect the information by applying the security rules.
also if you want to allow only the creator to write their own tasks you should also consider the case where you create the task and write something like this:
"tasks": {
//You need to include the $task_id otherwise the rule will seek the creatorId child inside task and not inside your auto-generated task
"$task_id": {
".read": "auth.uid === data.child('creatorId').val()",
//this is to validate that if you are creating a task it must have your own uid in the creatorId field and that you can only edit tasks that are yours...
".write":"(newData.child('creatorId').val() === auth.uid && !data.exists()) || (data.child('creatorId').val() === auth.uid && data.exists())",
//you should add the index on to tell firebase this is a query index so your queries can be efficient even with larger amounts of children
".indexOn":"creatorId",
}
}
(check the syntax but that's the general idea)
这篇关于Firebase对象所有权与事件观察的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!