Last active
August 10, 2023 07:11
-
-
Save blaugold/6e92b1b04af36e0525feef465c762137 to your computer and use it in GitHub Desktop.
Firebase Database Rules with TypeScript
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
// Use the TypeScript compiler to check your database rules. | |
// You'll get the most out of type checking if you define a database schema | |
// through interfaces and use it both in the web client and with the database rules. | |
// The compiler will catch misspellings and structural errors. | |
// It won't check for completeness since all properties are optional. | |
// Only works with TypeScript 2.1 and up because of mapped types being used. | |
interface DatabaseRuleSet { | |
'.read'?: string | boolean | |
'.write'?: string | boolean | |
'.validate'?: string | boolean | |
'.indexOn'?: string | string[] | |
} | |
// Union types of objects do not work as types for properties | |
// 16 levels since firebase allows max of 16 levels. | |
type RulesOf<A> = { | |
[B in keyof A]?: { | |
[C in keyof A[B]]?: { | |
[D in keyof A[B][C]]?: { | |
[E in keyof A[B][C][D]]?: { | |
[F in keyof A[B][C][D][E]]?: { | |
[G in keyof A[B][C][D][E][F]]?: { | |
[H in keyof A[B][C][D][E][F][G]]?: { | |
[I in keyof A[B][C][D][E][F][G][H]]?: { | |
[J in keyof A[B][C][D][E][F][G][H][I]]?: { | |
[K in keyof A[B][C][D][E][F][G][H][I][J]]?: { | |
[L in keyof A[B][C][D][E][F][G][H][I][J][K]]?: { | |
[M in keyof A[B][C][D][E][F][G][H][I][J][K][L]]?: { | |
[N in keyof A[B][C][D][E][F][G][H][I][J][K][L][M]]?: { | |
[O in keyof A[B][C][D][E][F][G][H][I][J][K][L][M][N]]?: { | |
[P in keyof A[B][C][D][E][F][G][H][I][J][K][L][M][N][O]]?: DatabaseRuleSet | |
} & DatabaseRuleSet | |
} & DatabaseRuleSet | |
} & DatabaseRuleSet | |
} & DatabaseRuleSet | |
} & DatabaseRuleSet | |
} & DatabaseRuleSet | |
} & DatabaseRuleSet | |
} & DatabaseRuleSet | |
} & DatabaseRuleSet | |
} & DatabaseRuleSet | |
} & DatabaseRuleSet | |
} & DatabaseRuleSet | |
} & DatabaseRuleSet | |
} & DatabaseRuleSet | |
} & DatabaseRuleSet | |
export interface DatabaseRules<Schema> { | |
rules: RulesOf<Schema> | |
} | |
// Define your database schema | |
interface UserData { | |
userName: string | |
email: string | |
signedUpAt: number | |
} | |
interface DatabaseSchema { | |
users: { | |
[uid: string]: UserData | |
} | |
} | |
// Use the DatabaseRules interface with your schema. | |
const rules: DatabaseRules<DatabaseSchema> = { | |
rules: { | |
users: { | |
'.read': 'auth != null', | |
'.write': 'auth.uid == $uid', | |
$uid: { | |
userName: { | |
'.validate': 'newData.isString() && newData.val().length >= 2' | |
}, | |
email: { | |
'.validate': 'newData.isString()' | |
}, | |
signedUpAt: { | |
'.validate': 'newData.isNumber()' | |
}, | |
} | |
} | |
} | |
}; | |
// Write the rules as json for deployment. | |
require('fs').writeFileSync('./database.rules.json', JSON.stringify(rules, null, 2)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment