CosmicSeizure
CosmicSeizure

Reputation: 1514

Firebase rules - read only value which was in query

I am storing usernames separately in validation section in the db. There are only usernames, so that when user is registering, he can enter the username and see if the username is available before he registers. The rules for that are now ".read": true , so that basically allows anyone to get easy access to all usernames in the db. I would want to prevent that, but i am not sure how to do that, since i cant use auth != null rule, because user was not created yet.

My only idea was to allow reading only the username which is requested, ie something

 firebase.database().ref('Validations/Usernames')
            .orderByChild('name')
            .equalTo(username)
            .once('value')
            .then(snapshot => ....

and then using rule like this:

"$name": {
   ".read": "query.equalTo == $name"
}

ie allow the read only for username which was checked from the client. Now, this fails because for all others its checking with orderByChild it does not have access to those.

Is there some similar way to allow to read only the value, which was requested to read from the client? Or perhaps there is some completely other way i should approach username validation before he created an account?

Upvotes: 0

Views: 40

Answers (1)

Frank van Puffelen
Frank van Puffelen

Reputation: 598857

If you only want to allow the user to check if the username they typed is already claimed, they don't read access on the entire Validations/Usernames node. Instead they only need read access on a specific child under that.

To allow this, make sure that you use the user names as the keys under Validations/Usernames, so something like:

"Validations": {
  "Usernames": {
    "CosmicSeizure": "uidOfCosmicSeizure",
    "puf": "uidOfPuf"
  }
}

With the above your rules can be:

"Validations": {
  "Usernames": {
    "$name": {
      ".read": true
    }
  }
}

And then you can check if a username exists with:

firebase.database().ref('Validations/Usernames')
        .child(username)
        .once('value')
        .then(snapshot => ....

And then you check if snapshot.exists().

Upvotes: 1

Related Questions