Firebase, decoded idToken is not the same as the token sent with REST

i am using firebase realtime database for my projects backend, but i have come upon a problem with making the security rules. I use REST to communicate with the database and to authorize the REST request i send an idToken as the query of the “auth=” parameter, as per https://firebase.google.com/docs/database/rest/auth.

Firebase only detects that i am authorized, but when i compare the auth.uid in the database rules they are not the same. I set up my own server and if i decode the token i see that it does hold the correct information of the user.

Here are my database rules i want to implement but they don’t work:

{
  "rules": {
      "$uid": {
        ".read": "auth.uid === $uid",
        ".write": "auth.uid === $uid"
      }
  }
} 

But these rules do work, which means i am authorized. Why does the auth object not hold the actual user id but some other value for auth.uid?

  "rules": {
      "$uid": {
        ".read": "auth != null",
        ".write": "auth != null"
      }
  }
}

Why does firebase decode the token differently? Can i even access the auth object that gets sent to the rules?

Answer

The auth object has 3 properties as listed below:

name description
provider The authentication method used (“password”, “anonymous”, “facebook”, “github”, “google”, or “twitter”).
uid A unique user id, guaranteed to be unique across all providers.
token The contents of the Firebase Auth ID token. See the reference documentation for auth.token for more details.

To access the decoded token including custom claims you can use auth.token. You can find more details about auth.token object in the documentation


Since your data is under a node 'data', you must specify that in rules:

{
  "rules": {
    "data": {
      "$uid": {
        ".read": "auth.uid === $uid",
        ".write": "auth.uid === $uid"
      }
    }
  }
}