Outline

When you first create a Firebase, the default security rules allow full read and write access. While this makes it a lot easier to get started developing, it's always strongly recommended that you create security rules to make sure that your data stays consistent and secured. There are three kinds of rules, .read, .write, and .validate for controlling access and validating your data.

Open up your Firebase Dashboard to the "Database" section and add the following rules to your Firebase
{
  "rules":{
    ".read": true,
    "users":{
      "$uid":{
        ".write": "auth !== null && $uid === auth.uid",
        "displayName":{
          ".validate": "newData.exists() && newData.val().length > 0"
        },
        "online":{
          "$connectionId":{
            ".validate": "newData.isBoolean()"
          }
        }
      }
    },
    "channels":{
      "$channelId":{
        ".write": "auth !== null",
        "name":{
          ".validate": "newData.exists() && newData.isString() && newData.val().length > 0"
        }
      }
    },
    "channelMessages":{
      "$channelId":{
        "$messageId":{
          ".write": "auth !== null && newData.child('uid').val() === auth.uid",
          ".validate": "newData.child('timestamp').exists()",
          "body":{
            ".validate": "newData.exists() && newData.val().length > 0"
          }
        }
      }
    },
    "userMessages":{
      "$uid1":{
        "$uid2":{
          "$messageId":{
            ".read": "auth !== null && ($uid1 === auth.uid || $uid2 === auth.uid)",
            ".write": "auth !== null && newData.child('uid').val() === auth.uid",
            ".validate": "$uid1 < $uid2 && newData.child('timestamp').exists()",
            "body":{
              ".validate": "newData.exists() && newData.val().length > 0"
            }
          }
        }
      }
    }
  }
}
 

I finished! On to the next chapter