FireBase - how to list user-specific data?

ε祈祈猫儿з 提交于 2020-01-10 07:43:45

问题


Currently I've been looking at FireBase, and have been using the AngularJS plugin, and have found the following problem I cannot get out of.

I currently have implemented the simple login system. Logged in with my mail and password after registering, I create a post like this:

post = {
 name: "Hi",
 message: "Guys",
 user_id: Auth.user.id // for my current user this is 1
}
posts.$add(post)

From this point on everything is fine. Now what I wanted to do is that in the posts/ endpoint on firebase, I want only to display the posts of the user currently logged in.

Other users may be able to read posts of others by having a public boolean variable (but that's for later)

I've been looking at the security API of Firebase (see: https://www.firebase.com/docs/security/security-rules.html) Currently I have this:

{
    "rules": {
        "posts": {
            "$post": {
              ".read": "data.child('user_id').val() == auth.id",
              ".write": "(data.child('user_id').val() == auth.id) || (newData.child('user_id').val() == auth.id)"
            }
        }   
    }
}

It works to a certain extend, I can write posts only if I'm logged in, but I cannot read any posts!

posts = new Firebase(base + '/posts')
posts = $firebase(posts)

The error is: FIREBASE WARNING: on() or once() for /posts failed: Error: permission_denied: Client doesn't have permission to access the desired data.

If anyone has a solution then that would be awesome!


回答1:


Security rules cannot be used as data filters. You can't just read the entire posts path and expect to only retrieve the records you're allowed to see. Instead, you need to architect your data in a manner that you can read the whole path, or store an index of which records are viewable and fetch them separately.

For example, store the records by group ids or by user ids:

/posts/$group/data...
/posts/$user/data...

And then you can ensure your users have permissions by assigning them to appropriate groups, and simply fetching the messages for those groups:

var ref = new Firebase(base + '/posts/' + GROUP_ID);
var posts = $firebaseArray(ref);

Or you can create an index of messages each user/group/etc may view:

/posts/$post_id/data...
/posts_i_can_view/$user_id/$post_id/true

And fetch them individually from the master list. A tool like Firebase-util will make this much simpler:

var fb = new Firebase(base);
var ref = Firebase.util.NormalizedCollection(
   fb.child('posts_i_can_view/'+USER_ID),
   fb.child('posts')
)
.select('posts.message', 'posts.user_id')
.ref();

var posts = $firebaseArray(ref);

Further reading on Firebase data structures:

https://www.firebase.com/docs/web/guide/structuring-data.html https://www.firebase.com/docs/web/guide/understanding-data.html https://www.firebase.com/blog/2013-04-12-denormalizing-is-normal.html



来源:https://stackoverflow.com/questions/21500946/firebase-how-to-list-user-specific-data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!