Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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" : "[email protected]"
      }
    },
    "YgSfSzPzxLbyDL17r6P9id2cdvH2" : {
      "Name:" : "Example 2",
      //This public child should be accessible by 
      //"Example 1" but cannot know the name of 
      // this user
      "public" : {
        "email" : "[email protected]"
      }
    }
  }
}

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.

like image 554
user2884707bond Avatar asked Aug 12 '16 15:08

user2884707bond


People also ask

How do I use Firebase authentication?

To build user-based and role-based access systems that keep your users' data safe, use Firebase Authentication with Firebase Security Rules. Authentication identifies users requesting access to your data and provides that information as a variable you can leverage in your rules.

What are firebase security rules?

Firebase Security Rules provide access control and data validation in a format that supports multiple levels of complexity. To build user-based and role-based access systems that keep your users' data safe, use Firebase Authentication with Firebase Security Rules.

How do I restrict access to my data in Firebase?

When you create a database or storage instance in the Firebase console, you choose whether your Firebase Security Rules restrict access to your data ( Locked mode ) or allow anyone access ( Test mode ). In Cloud Firestore and Realtime Database, the default rules for Locked mode deny access to all users.

Is it safe to deploy an app on Firebase?

Also remember that if you deploy your app, it's publicly accessible — even if you haven't launched it. Remember that Firebase allows clients direct access to your data, and Firebase Security Rules are the only safeguard blocking access for malicious users.


2 Answers

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" : "[email protected]"
    },
    "YgSfSzPzxLbyDL17r6P9id2cdvH2" : {
      "email" : "[email protected]"
    }
  }
}

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.

like image 120
Frank van Puffelen Avatar answered Oct 21 '22 13:10

Frank van Puffelen


Hmm wouldn't it be easier to (re)structure the db so that you have a public and a private field per user? Something like:

{
  "users" : {
    "YFIIAgwa2kaannrXjwvSZmoywma2" : {
      "private": { 
        "Name:" : "Example 1" 
      },
      "public" : {
        "email" : "[email protected]"
      }
    },
    "YgSfSzPzxLbyDL17r6P9id2cdvH2" : {
      "private": { 
        "Name:" : "Example 2" 
      },
      "public" : {
        "email" : "[email protected]"
      }
    }
  }
}

/UPD: This way it should be easy(er) to have the different permissions because they won't inherit them from the parent?

like image 39
REJH Avatar answered Oct 21 '22 13:10

REJH