1
votes

These are my security rules regarding the users node in my database.

    "users": {
      "$uid": {
        ".read": "auth != null && $uid === auth.uid",
        "$user_nodes": {
          ".write": "(auth != null && $uid === auth.uid) || (auth == null && $user_nodes.contains('connection'))"
        }
      }
    }

With these rules when I am authenticated and try to read the whole information under my auth.uid everything works. For some reason though set operations are not allowed for the whole node, but update operations are. Can someone clearify to me why this is so?

EDIT: So in code a read operation would look something like this:

userRef.child(auth.getCurrentUser().getUid()).addListenerForSingleValueEvent(new ValueEventListener() {...});

A set operation would look something like this:

userRef.child(auth.getCurrentUser().getUid()).setValue(...);

I cannot show you exact code because the behaviour I explained above I actually experienced when testing the rules in the rules playground.

1
Please edit the question to show examples of app code that does not work the way you expect with these rules. We should be able to copy what you show and run it for ourselves to observe the same behavior. - Doug Stevenson
@DougStevenson I edited the question just now. But as I said there I can't really show exact code because the behaviour was experienced in the rules playground. It is not really a big problem for my app but I just wanted to know why in the rules playground update operations for the whole node $uid are allowed but set operations are not with these exact rules. - Veselin Zinkov

1 Answers

1
votes

This is your code:

userRef.child(auth.getCurrentUser().getUid()).setValue(...);

This code tries to do a set on /users/$uid, which is not allowed according to your security rules. So if the write gets rejected, that is working as intended.

With your rules a client can write or delete any child node, but it can't write or delete /users/$uid itself. That is also why an update statement works: that effectively executes a set() operation on each property that is present in the update call, which is allowed according to the rules.

It might be easiest to see the difference here by thinking of delete operation: your rules allow a user to delete any child node of /users/$uid, but they can't delete /users/$uid all in one go.