Last active
November 3, 2022 16:10
-
-
Save prilaga/28ddd15f00e06feab5b850c53da4d4ed to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"rules": { | |
// Admin access. | |
".read": "auth.token.admin === true", | |
".write": "auth.token.admin === true", | |
"admins": { | |
".read": "false", // Only a cloud function or admins can update this. | |
".write": "false", // Only a cloud function or admins can update this. | |
"$index": { | |
"email": { | |
".validate": "newData.isString()" | |
} | |
} | |
}, | |
// User's personnal feeds. | |
"feed": { | |
"$uid": { | |
".read": "auth.uid === $uid", | |
".write": "auth.uid === $uid", | |
"$postId": { | |
".validate": "newData.val() === true && newData.parent().parent().parent().child('posts').child($postId).exists()" | |
} | |
} | |
}, | |
// List of all Posts. | |
"posts": { | |
".read": true, | |
".indexOn": ["author/uid", "timestamp"], // Allow searching for posts by authors. Useful for deletion. | |
"$postId": { | |
".write": "!data.exists() || data.exists() && auth.uid === data.child('author').child('uid').val()", // Allow new writes and allow updates and deletes to own posts. | |
".validate": "newData.child('author').child('uid').exists() && newData.child('text').exists()", | |
"text": { | |
".validate": "newData.isString() && newData.val().length < 2000" | |
}, | |
"timestamp": { | |
".validate": "newData.val() === now" | |
}, | |
"client": { | |
".validate": "newData.val() === 'web' || newData.val() === 'ios' || newData.val() === 'android'" | |
}, | |
"sanitized": { | |
".validate": "false" // Only a cloud function (admin mode) can update this. | |
}, | |
"moderated": { | |
".validate": "false" // Only a cloud function (admin mode) can update this. | |
}, | |
"author": { | |
"uid": { | |
".validate": "auth.uid === newData.val()" | |
}, | |
"full_name": { | |
".validate": "auth.token.name === newData.val() || (auth.token.name === null && newData.val() === 'Anonymous')" | |
}, | |
"profile_picture": { | |
".validate": "true" | |
} | |
} | |
} | |
}, | |
// Post's comments. | |
"comments": { | |
".read": true, | |
"$postId": { | |
".indexOn": "author/uid", // Allow searching for comments by authors. Useful for deletion. | |
".write": "!newData.exists() && auth.uid === root.child('posts').child($postId).child('author').child('uid').val() && !newData.parent().parent().child('posts').child($postId).exists()", // Allow deletes from the post owner | |
".validate": "root.child('posts').child($postId).exists()", // Check that the post exists | |
"$commentId": { | |
".write": "(!data.exists() || data.exists() && auth.uid === data.child('author').child('uid').val()) && (root.child('blocked').child(auth.uid).child(root.child('posts').child($postId).child('author').child('uid').val()).val() !== true)", // Can write new comments and edit/delete particular comment if you are the author. | |
"text": { | |
".validate": "newData.isString() && newData.val().length < 2000" | |
}, | |
"sanitized": { | |
".validate": "false" // Only a cloud function (admin mode) can update this. | |
}, | |
"moderated": { | |
".validate": "false" // Only a cloud function (admin mode) can update this. | |
}, | |
"timestamp": { | |
".validate": "newData.val() === now" | |
}, | |
"author": { | |
"uid": { | |
".validate": "auth.uid === newData.val()" | |
}, | |
"full_name": { | |
".validate": "auth.token.name === newData.val() || (auth.token.name === null && newData.val() === 'Anonymous')" | |
}, | |
"profile_picture": { | |
".validate": "true" | |
}, | |
"$other": { | |
".validate": false | |
} | |
}, | |
"$other": { | |
".validate": false | |
} | |
} | |
} | |
}, | |
// Hashtag index. | |
"hashtags": { | |
".read": true, | |
".write": false | |
}, | |
// List of post's likes. | |
"likes": { | |
".read": true, | |
"$postId": { | |
".write": "!newData.exists() && auth.uid === root.child('posts').child($postId).child('author').child('uid').val() && !newData.parent().parent().child('posts').child($postId).exists()", // Allow deletes from the post owner | |
".validate": "root.child('posts').child($postId).exists()", // Check that the post exists | |
"$uid": { | |
".write": "auth.uid === $uid", | |
".validate": "newData.val() === now" | |
} | |
} | |
}, | |
// List of followers. | |
"followers": { | |
".read": true, | |
"$followedUid": { | |
"$followerUid": { | |
".write": "auth.uid === $followerUid", // Can only add yourself as a follower | |
".validate": "newData.val() === true && newData.parent().parent().parent().child('people').child($followerUid).child('following').child($followedUid).exists()" // Makes sure /people/.../following is in sync | |
} | |
} | |
}, | |
// Public profile information. | |
"people": { | |
".indexOn": ["_search_index/full_name", "_search_index/reversed_full_name"], | |
".read": true, | |
"$uid": { | |
".write": "auth.uid === $uid", | |
"full_name": { | |
".validate": "auth.token.name === newData.val() || (auth.token.name === null && newData.val() === 'Anonymous')" | |
}, | |
"profile_picture": { | |
".validate": "true" | |
}, | |
"posts": { | |
"$postId": { | |
".validate": "newData.val() === true && newData.parent().parent().parent().parent().child('posts').child($postId).exists()" | |
} | |
}, | |
"_search_index": { | |
"full_name": { | |
".validate": "newData.isString()" | |
}, | |
"reversed_full_name": { | |
".validate": "newData.isString()" | |
} | |
}, | |
"following": { | |
"$followedUid": { | |
".validate": "newData.parent().parent().parent().parent().child('followers').child($followedUid).child($uid).val() === true" // Makes sure /followers is in sync | |
} | |
} | |
} | |
}, | |
// List of blocked users. | |
"blocking": { | |
"$blockerUid": { | |
".write": "auth.uid === $blockerUid", // Can only add yourself as a blocker | |
".read": "auth.uid === $blockerUid", | |
"$blockedUid": { | |
".read": "auth.uid === $blockedUid", | |
".validate": "newData.val() === true && newData.parent().parent().parent().child('blocked').child($blockedUid).child($blockerUid).exists()" // Makes sure /blocked is in sync | |
} | |
} | |
}, | |
// List of blocking users. | |
"blocked": { | |
"$blockedUid": { | |
".read": "auth.uid === $blockedUid", | |
"$blockerUid": { | |
".read": "auth.uid === $blockerUid", | |
".write": "auth.uid === $blockerUid", // Can only add yourself as a blocker | |
".validate": "newData.val() === true && newData.parent().parent().parent().child('blocking').child($blockerUid).child($blockedUid).exists()" // Makes sure /blocker is in sync | |
} | |
} | |
}, | |
// List of flagged posts. | |
"postFlags": { | |
"$postId": { | |
".validate": "root.child('posts').child($postId).exists()", // Check that the post exists | |
"$uid": { | |
".write": "auth.uid === $uid", | |
".read": "auth.uid === $uid", | |
".validate": "newData.val() === true" | |
} | |
} | |
}, | |
// List of flagged comments. | |
"commentFlags": { | |
"$postId": { | |
".validate": "root.child('posts').child($postId).exists()", // Check that the post exists | |
"$commentId": { | |
".validate": "root.child('comments').child($postId).child($commentId).exists()", // Check that the comment exists | |
"$uid": { | |
".write": "auth.uid === $uid", | |
".read": "auth.uid === $uid", | |
".validate": "newData.val() === true" | |
} | |
} | |
} | |
}, | |
// Privacy settings | |
"privacy": { | |
"$uid": { | |
".write": "auth.uid === $uid", | |
".read": "auth.uid === $uid", | |
"data_processing": { | |
".validate": "newData.isBoolean()" | |
}, | |
"content": { | |
".validate": "newData.isBoolean()" | |
}, | |
"social": { | |
".validate": "newData.isBoolean()" | |
}, | |
"$other": { | |
".validate": "false" | |
} | |
} | |
}, | |
// Disallow all other attributes. | |
"$other": { | |
".validate": false | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment