wle8300
wle8300

Reputation: 2749

Invalid data still emits "child_added" events?

const uid = Firebase.auth().currentUser.uid
const itemId = Firebase.database().ref('user_items/' +uid+ '/items').push().key    

Firebase.database().ref('user_items/' +uid+ '/items/' +itemId)
.set({
  BUTTS: Firebase.database.ServerValue.TIMESTAMP,
  foo: 'bar'
})

I have validation rules that shouldn't allow "BUTTS" as a key. When I run the piece of code below I get an error in console (as expected)... but my child_added listener still emits with that gluteus maximalistic new data.

Is this expected behavior? Should I be listening to a different event?


EDIT: Adding my rules

{
  "rules": {
    "users": {
      "$user": {
        ".read": "$user === auth.uid",
        ".write": "$user === auth.uid",
      }
    },
    "user_items": {
      "$user": {
        ".read": "auth.uid === $user",
        ".write": "auth.uid === $user",
        "items": {
          "$item": {
            ".validate": "newData.hasChildren(['a', 'foo'])",
            "$other": {
              ".validate": "false"
            },
            ".read": "auth.uid === $user",
            ".write": "auth.uid === $user",
            "a": {
              ".validate": "newData.isString()"
            },
            "foo": {
              ".validate": "newData.isString()"
            }
          }
        }
      }
    }
  }
}

Upvotes: 1

Views: 79

Answers (1)

Bob Snyder
Bob Snyder

Reputation: 38289

Yes, this is the expected behavior. It's all explained in this Firebase blog post.

Permissions are enforced on the server, not the client. To improve responsiveness, the listeners fire immediately when a change is detected in the client. If the change is rejected by the server, the client is notified and listener events are fired to reverse the change. This is summarized at the end of the blog post:

When there is an update to a location that also has active listeners in the same process, the flow of data through the process goes like this:

  1. Immediately call all relevant listeners with the new value
  2. Send the update to the Firebase server side
  3. Check security rules for validity
  4. If a security rule was violated, notify the client SDK
  5. Roll back the change in the app by calling relevant listeners again to back to the original state

You will need to listen for both child_added and child_removed events and respond as needed to handle permission failures.

Upvotes: 2

Related Questions