1

I am having an issue comparing the time interval that I have saved in my firebase db to the 'now' firebase security rule. The rule I am writing is intended to prevent users from reading if a post is after a certain time. This is how I am saving the timestamp in my database:

"time":  NSDate().timeIntervalSince1970

This is the security rule I am writing that should prevent a read if after a certain time:

"follower-feed": {
  // ".read": "auth !== null",
  ".write": "auth !== null",
    "$userID": {
    "$postID": {
      ".read": "auth !== null && data.child('time').val() >= ((now / 1000) - 86400)",}}},

And this is the database schema I am using to store posts:

-follower-feed: {

user_uid_1: {

post_uid_1: {

     "time": 1515435031.16646

post_uid_2: {

     "time": 1515435091.22323

I would like to note that I am already accounting for the fact that 'now' is in milliseconds and dividing it by 1,000 should set my two numbers to the same time value of seconds. I have stifled all about the firebase documentation but nothing is helping me solve this. When I run the simulator test to determine if the requested read will pass, it says that it will pass. However, in my app no data is being read.

This is the code that attempts to read the data from firebase:

    var followingPosts = [Post]()
func loadUserFeed(_ update: @escaping () -> Void) {
    userFeedHandle = CURRENT_USER_FEED_REF.observe(DataEventType.value, with: {(snapshot) in
        self.followingPosts.removeAll()
        for child in snapshot.children.allObjects as! [DataSnapshot] {
            let post = Post(postID: child.key, postData: child.value as! Dictionary<String, Any>)
            self.followingPosts.append(post)
            self.followingPosts.sort(by: {  Double(truncating: $0.time) >  Double(truncating: $1.time)})
            update()
        }
        if snapshot.childrenCount == 0 {
            update()
        }

    })

}
Chris
  • 387
  • 5
  • 18
  • If you uncomment the rule `".read": "auth !== null"` is the data read successfully? – Bob Snyder Jan 08 '18 at 18:50
  • yea, if I put the rule at the top of the node, it is read successfully – Chris Jan 08 '18 at 19:06
  • Can you post the code that attempts to read the DB and fails? The rule is correct and works for me using an Android client when I request a read of `/follower-feed/some-userID/some-postID`. Note that rules are not filters. You have no rules for locations `follower-feed` or `follower-feed/$userID`, so if you request a query at those locations, it will fail. – Bob Snyder Jan 08 '18 at 20:03
  • sure thing, I updated my post – Chris Jan 08 '18 at 20:12

1 Answers1

1

It appears that CURRENT_USER_FEED_REF is the location containing a given user's posts, i.e. follower-feed/$userID, and that you were expecting that the security rule for post age would act a filter, allowing the user's recent posts to be returned by the query and old posts to be excluded. But security rules are not filters. For any location, you'll either be able to read all of the data (including its children), or none of it. You have no rule allowing read at follower-feed/$userID, so a query at that location will fail.

See this answer from a Firebase team-member for an idea on how to implement what you want, or search for "firebase rules are not filters" to see other related questions and answers.

Bob Snyder
  • 37,759
  • 6
  • 111
  • 158
  • Thank you for the clarification on what they define as a filter. That was the problem I was having, I think that adding a query start and end may fair me better. Thanks – Chris Jan 08 '18 at 20:44