Firebase Security

INTRO

Folks normally get to firebase security after they have already dived in and half created their app. This is the wrong approach. Security needs to be considered from the outset, sort that out first, then the rest will follow...

Why do we need to secure our Firebase data:


Firebase provides for all forms of fancy and conditional rules that can be applied to your data, my aim here is to just set out the main three or four basic sets of rules to get you going.

You can refer to the Firebase Documentation on Securing your Data. I have attempted to keep this as simple as possible, and, under the defining "rules", I have always set a ProjectBucket - this can be any path, sometimes several layers deep, to the data.

Firebase Rules are held and edited in Firebase via the Firebase Console

Firebase Realtime Database Rules

{

  "rules": {

       "<ProjectBucket>": {

            ".read" : true,

            ".write": true

       }

   }

}

{

  "rules": {

    "<ProjectBucket>": {

    ".read": "auth.uid != null",

      ".write": "auth.uid != null"

    }

  }

}

  "rules": {

    "<ProjectBucket>": {

      "$uid": {

        ".read": true,

        // or ".read": "auth.uid != null" for only authenticated users

        ".write": "auth.uid == $uid"

      }

    }

  }

}

{

  "rules": {

    "<ProjectBucket>": {

       "$uid": {

         ".read": "$uid === auth.uid",

         ".write": "$uid === auth.uid"

       }

     }

   }

}


Once development is done, you should, as a bare minimum, be using rules as in 2. That said, this will mean you will need to organise authentication for your users!


Here is where you edit the Realtime Database rules on the console:

Firebase Storage Rules

rules_version = '2';

service firebase.storage {

  match /b/{bucket}/o {

    match /{allPaths=**} {

      allow read, write: if true;

    }

  }

}

service firebase.storage {

  match /b/{bucket}/o {

    match /{allPaths=**} {

      allow read, write: if request.auth != null;

    }

  }

}

rules_version = '2';

service firebase.storage {

  match /b/{bucket}/o {

    match /{allPaths=**} {

      allow read: if true

      allow write:  if request.auth != null;

    }

  }

}


As a minimum, once development is finished, you should be using rules as in 3, but if you need to protect the files from anyone viewing, then use rules in 2.


Here is where you edit Storage rules on the console:

In App Inventor

We will also need to apply some rules to development and production in App Inventor, because here we will be using the access keys in order to complete Firebase requests. Just as you see when using the experimental component or firebase extensions we will need to use the "API key", the "Firebase URL", and the "Storage App ID". These can all be found on the project settings pages for the database and storage elements. We need to keep these keys secure and away from prying eyes.


In Closing

Ok, so now we know all about Firebase rules, why they are important, and when to use them. 

We will now move on to PART II, which somewhat perversely, sets up a demo using Firebase with no rules! ... tiny steps ....