Firebase对象所有权与事件观察 [英] Firebase Object Ownership with Event Observation

查看:123
本文介绍了Firebase对象所有权与事件观察的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在iOS应用中使用了Firebase。我希望每个对象都有一个 creatorId 属性,其值是经过身份验证的用户标识( authData.uid 使用Firebase身份验证对象)。我使用自定义令牌生成器进行身份验证,但问题可以通过匿名登录进行复制。



我希望用户只能读取(和写,但让我们专注于现在阅读,因为这是我有我的问题)他们创建的对象。换句话说,查询用户的认证用户ID将匹配它们所提取对象的 creatorId



I我在制作查询和规则时遇到了权限问题。



$ / / b
$ b

以下是我的Firebase信息中心对于任务对象:

  + firebase-base 
+ tasks
+ {task_id}
+ creatorId:
+ title:

其中 task_id 是Firebase在插入时生成的唯一标识符。



我的规则看起来像这样(再次,让我们忽略现在写规则):

  {
rules:{
tasks:{
$ task_id:{
.read:auth.uid === data.child('crea val()
}
}
}
}

读取一个特定的任务可以正常工作,但是我希望能够使用 observeEventType 和相关功能。这对我不起作用。

下面是我在Swift中观察的内容:



<$ p $ Firebase(url:https:// {My-Firebase-Base-Reference} / tasks)
reference.observeEventType(.ChildChanged,
withBlock: {(snapshot:FDataSnapshot!) - >无效
$ b $ //成功

}){(error:NSError!)in

/ /错误:我在这里得到权限被拒绝。




$ b根据@ Ymmanuel的建议,我也尝试过更具体的我的查询,如下所示:

  let reference = Firebase(url:https:// {My-Firebase-Base-Reference queryEventTo({USER_UID})。observeEventType(.ChildChanged,
withBlock:{(snapshot:FDataSnapshot!) - >无效

//成功

}){(error:NSError!)in

//错误:我在此处获得权限被拒绝。






这两个模块都没有工作,我总是得到Permission Denied 错误。我在做什么错了?

解决方案

你缺少的是你假设安全规则是查询,这是不正确的。



检查
规则不是过滤部分链接。



安全规则只验证您是否可以读取或写入特定的Firebase路径数据库。



例如,如果您只想接收特定用户的更改,则应使用firebase查询。您想要获取特定用户的所有任务,您应该这样做:

  let reference = Firebase(url:https: (creatorId)。q​​ueryEqualTo(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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆