Skip to content

Instantly share code, notes, and snippets.

@blaugold
Last active August 10, 2023 07:11
Show Gist options
  • Save blaugold/6e92b1b04af36e0525feef465c762137 to your computer and use it in GitHub Desktop.
Save blaugold/6e92b1b04af36e0525feef465c762137 to your computer and use it in GitHub Desktop.
Firebase Database Rules with TypeScript
// 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