user2884707bond user2884707bond - 3 months ago 38
JSON Question

How to create public/private user profile with Firebase security rules?

{
"rules": {
"users": {
"$uid":{
//Private whatever under "uid" but Public is exposed
".read": "auth != null && auth.uid == $uid",
".write": "auth != null && auth.uid == $uid",

"public": { ".read": "auth != null" }
}
}
}
}



  • I've created these rules to have users public/private profile

  • "users/{uid}/public" profile should be accessible by any users those are authenticated, but cannot access the data under "users/uid"



Here is some fake data that is stored in my firebase database.

{
"users" : {
"YFIIAgwa2kaannrXjwvSZmoywma2" : {
"Name:" : "Example 1",
//This public child should be accessible by
//"Example 2" but cannot know the name of
// this user
"public" : {
"email" : "example1@gmail.com"
}
},
"YgSfSzPzxLbyDL17r6P9id2cdvH2" : {
"Name:" : "Example 2",
//This public child should be accessible by
//"Example 1" but cannot know the name of
// this user
"public" : {
"email" : "example2@gmail.com"
}
}
}
}


I want to know if this is the robust way to prevent any users from accessing user's critical information! Is there anyway I can improve this by using validate? I am open to any suggestions you guys have. I want to create the best and simple security rules for my app.

Answer

You can definitely secure access to the private and public data with your current data structure.

But one use-case you'll likely want at some point is to show a list of the public info for all users. With your current data structure that is not possible, because Firebase's security model cannot be used to filter data. For a great answer covering this, see Restricting child/field access with security rules.

Most developers split the public and private data in completely separate subtrees:

{
  "users" : {
    "YFIIAgwa2kaannrXjwvSZmoywma2" : {
      "Name:" : "Example 1",
    },
    "YgSfSzPzxLbyDL17r6P9id2cdvH2" : {
      "Name:" : "Example 2",
    }
  },
  "public_profiles": {
    "YFIIAgwa2kaannrXjwvSZmoywma2" : {
      "email" : "example1@gmail.com"
    },
    "YgSfSzPzxLbyDL17r6P9id2cdvH2" : {
      "email" : "example2@gmail.com"
    }
  }
}

You can then secure access with:

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

Now any authenticated user can listen to /public_profiles, which means you can easily show a list of these profiles.