2

I am having an issue when trying the following validation rule:

            ".validate": "newData.val() >= now - 2000 && newData.val() >= data.parent().parent().parent().parent().parent().child('users/'+auth.uid+'/lastPostAt').val() - 2000"

Here are the relevant area's of my Firebase database schema:

areas
    -> area1
        -> posts
            -> uid
                 -> post object ( has timestamp property (date) - firebase timestamp)


user
    -> uid
         -> user object ( has timestamp property (lastPostAt) - Firebase timestamp)

When a post is submitted it updates the lastPostAt timestamp property in the user object for the specific user that submitted the post.

What I am looking for is some Firebase rules to ensure that when a new post is submitted that it is not stored unless the user has not submitted another post within the last 2 minutes.

I have look at this post on StackOverflow, but I am trying to see if it is possible to do this with my implementation.

Under the $uid for my posts node, I am trying a .validate rule:

        "posts" : {
           "$message_id": {
                ".indexOn": "username",
                ".write": "newData.hasChildren(['date'])",
                "date" : {
                    ".validate": "newData.val() >= now - 2000 && newData.val() >= data.parent().parent().parent().parent().parent().child('users/'+auth.uid+'/lastPostAt').val() - 2000"
            }

Currently, when I submit a post, both the timestamps are the same, but I can keep posting more and more posts with no delay.

Community
  • 1
  • 1
Fred
  • 147
  • 1
  • 1
  • 8
  • 2
    Why did you delete [your previous post](http://stackoverflow.com/questions/41124660/firebase-rules-to-prevent-spam) and add a new one? If you have details to add, please add them to your original question next time. – Frank van Puffelen Dec 13 '16 at 23:27
  • You can use `root.child('users/'+auth.uid+'/lastPostAt')` instead of `data.parent().parent().parent().parent().parent().child('users/'+auth.uid+'/lastPostAt')` – Chemical Programmer Jan 28 '17 at 04:41

1 Answers1

2

If you want to prevent additional posts for two minutes, newData.val() needs to be at least 120,000 milliseconds greater than lastPostAt.

So your rule should be:

"date" : {
    ".validate": "newData.val() >= now - 2000 && newData.val() >= data.parent().parent().parent().parent().parent().child('users/'+auth.uid+'/lastPostAt').val() + 120000"
}

Also, if you are using ServerValue.TIMESTAMP, you can use:

newData.val() === now

Using this in the rule would prevent arbitrary, future timestamps from being used. (And if you are not using ServerValue.TIMESTAMP, you should consider using it.)

cartant
  • 57,105
  • 17
  • 163
  • 197