Firebase Realtime Database
backend
TypeScript
scaffolding
zen
Build real-time applications with Firebase Realtime Database including security rules.
By emily_r
12/8/2025
Prompt
Build a real-time application for [APPLICATION_NAME] using Firebase Realtime Database with [FRAMEWORK].
Requirements
1. Application Setup
Initialize Firebase in your application:
- Project name: [APPLICATION_NAME]
- Framework: [React/Vue/Angular/React Native/Flutter]
- Features needed: [Real-time chat/Live updates/Collaborative editing/etc.]
- Authentication: [Email/Google/Anonymous/Phone]
- Data entities: [ENTITY_1], [ENTITY_2], [ENTITY_3]
2. Database Structure Design
Create a denormalized data structure optimized for Firebase:
{
"[entities]": {
"[entity_id]": {
"id": "[entity_id]",
"[field1]": "[value]",
"[field2]": "[value]",
"createdAt": 1234567890,
"updatedAt": 1234567890,
"userId": "[user_id]"
}
},
"users": {
"[user_id]": {
"uid": "[user_id]",
"displayName": "[name]",
"email": "[email]",
"photoURL": "[url]",
"createdAt": 1234567890
}
},
"userProfiles": {
"[user_id]": {
"[entity_id]": true // For quick lookups
}
}
}
3. Firebase Configuration
Set up Firebase SDK:
Web (React/Vue/Angular):
// firebase.ts
import { initializeApp } from 'firebase/app'
import { getDatabase, ref, onValue, set, update, remove, push } from 'firebase/database'
import { getAuth } from 'firebase/auth'
const firebaseConfig = {
apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
databaseURL: process.env.NEXT_PUBLIC_FIREBASE_DATABASE_URL,
projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID
}
const app = initializeApp(firebaseConfig)
export const db = getDatabase(app)
export const auth = getAuth(app)
React Native:
import { initializeApp } from '@react-native-firebase/app'
import database from '@react-native-firebase/database'
const firebaseConfig = { /* config */ }
const app = initializeApp(firebaseConfig)
export const db = database()
4. CRUD Operations
Implement complete data operations:
Create
import { ref, push, set } from 'firebase/database'
async function create[Entity]([entity]Data: [Entity]) {
const [entities]Ref = ref(db, '[entities]')
const new[Entity]Ref = push([entities]Ref)
const [entity] = {
id: new[Entity]Ref.key,
...[entity]Data,
createdAt: Date.now(),
updatedAt: Date.now(),
userId: auth.currentUser?.uid
}
await set(new[Entity]Ref, [entity])
// Add to user profile index
if (auth.currentUser) {
await set(ref(db, `userProfiles/${auth.currentUser.uid}/${new[Entity]Ref.key}`), true)
}
return [entity]
}
Read (Real-time)
import { ref, onValue, off } from 'firebase/database'
function subscribe[Entities](callback: ([entities]: [Entity][]) => void) {
const [entities]Ref = ref(db, '[entities]')
const unsubscribe = onValue([entities]Ref, (snapshot) => {
const data = snapshot.val()
const [entities]: [Entity][] = data
? Object.values(data)
: []
callback([entities])
})
// Return cleanup function
return () => off([entities]Ref, 'value', unsubscribe)
}
// Usage in React
useEffect(() => {
const unsubscribe = subscribe[Entities](set[Entities])
return unsubscribe
}, [])
Read (One-time)
import { ref, get } from 'firebase/database'
async function get[Entity](id: string): Promise<[Entity] | null> {
const [entity]Ref = ref(db, `[entities]/${id}`)
const snapshot = await get([entity]Ref)
if (snapshot.exists()) {
return snapshot.val() as [Entity]
}
return null
}
Update
import { ref, update } from 'firebase/database'
async function update[Entity](id: string, updates: Partial<[Entity]>) {
const [entity]Ref = ref(db, `[entities]/${id}`)
await update([entity]Ref, {
...updates,
updatedAt: Date.now()
})
}
Delete
import { ref, remove } from 'firebase/database'
async function delete[Entity](id: string) {
const [entity]Ref = ref(db, `[entities]/${id}`)
await remove([entity]Ref)
// Remove from user profile index
if (auth.currentUser) {
await remove(ref(db, `userProfiles/${auth.currentUser.uid}/${id}`))
}
}
5. Advanced Queries
Implement filtering and sorting:
import { ref, query, orderByChild, equalTo, limitToFirst, startAt, endAt } from 'firebase/database'
// Query by field
function get[Entities]ByUser(userId: string) {
const [entities]Ref = ref(db, '[entities]')
const userQuery = query(
[entities]Ref,
orderByChild('userId'),
equalTo(userId)
)
return onValue(userQuery, (snapshot) => {
const data = snapshot.val()
return data ? Object.values(data) : []
})
}
// Pagination
function get[Entities]Paginated(limit: number, startAfterKey?: string) {
const [entities]Ref = ref(db, '[entities]')
const paginatedQuery = startAfterKey
? query([entities]Ref, orderByChild('createdAt'), startAt(startAfterKey), limitToFirst(limit))
: query([entities]Ref, orderByChild('createdAt'), limitToFirst(limit))
return get(paginatedQuery)
}
6. Security Rules
Implement comprehensive Firebase security rules:
{
"rules": {
"users": {
"$uid": {
".read": "$uid === auth.uid",
".write": "$uid === auth.uid",
".validate": "newData.hasChildren(['uid', 'displayName', 'email'])"
}
},
"[entities]": {
"$[entity]Id": {
".read": "auth != null",
".write": "auth != null && (!data.exists() || data.child('userId').val() === auth.uid)",
".validate": "newData.hasChildren(['id', 'userId', 'createdAt'])",
"userId": {
".validate": "newData.val() === auth.uid"
},
"[field1]": {
".validate": "newData.isString() && newData.val().length > 0 && newData.val().length <= 100"
},
"[field2]": {
".validate": "newData.isNumber()"
}
}
},
"userProfiles": {
"$uid": {
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
}
}
}
}
7. Offline Persistence
Enable offline support:
import { enableDatabase } from 'firebase/database'
// Enable offline persistence
enableDatabase(db)
// Monitor connection state
import { ref, onValue } from 'firebase/database'
const connectedRef = ref(db, '.info/connected')
onValue(connectedRef, (snapshot) => {
if (snapshot.val() === true) {
console.log('Connected to Firebase')
} else {
console.log('Offline mode')
}
})
8. Real-time Features
Implement presence and typing indicators:
// User presence
import { ref, onDisconnect, set, serverTimestamp } from 'firebase/database'
async function setUserPresence(userId: string, status: 'online' | 'offline') {
const presenceRef = ref(db, `presence/${userId}`)
// Set online
await set(presenceRef, {
status: 'online',
lastSeen: serverTimestamp()
})
// Set offline on disconnect
onDisconnect(presenceRef).set({
status: 'offline',
lastSeen: serverTimestamp()
})
}
// Typing indicator
async function setTypingIndicator(chatId: string, userId: string, isTyping: boolean) {
const typingRef = ref(db, `chats/${chatId}/typing/${userId}`)
if (isTyping) {
await set(typingRef, true)
onDisconnect(typingRef).remove()
} else {
await remove(typingRef)
}
}
9. Performance Optimization
Implement best practices:
// Use shallow queries for large lists
import { ref, query, orderByKey, limitToLast } from 'firebase/database'
const recentItemsQuery = query(
ref(db, '[entities]'),
orderByKey(),
limitToLast(20)
)
// Index data for queries (in security rules)
{
"rules": {
"[entities]": {
".indexOn": ["userId", "createdAt", "status"]
}
}
}
// Denormalize data to avoid deep queries
// Instead of: /users/{uid}/posts/{postId}/comments/{commentId}
// Use: /comments/{commentId} with userId and postId fields
Implementation Checklist
- Initialize Firebase with configuration
- Set up authentication
- Design denormalized database structure
- Implement CRUD operations
- Add real-time listeners
- Write security rules
- Enable offline persistence
- Add presence/typing indicators
- Implement pagination
- Add data validation
- Set up indexes for queries
- Test security rules
- Handle edge cases (network errors, race conditions)
Expected Deliverables
- Firebase configuration with environment variables
- Complete CRUD operations for all entities
- Security rules protecting user data
- Real-time subscriptions with cleanup
- Offline support enabled
- Type definitions for all data models
- Error handling for network issues
Tags
firebase
realtime
database
nosql
Tested Models
gpt-4
claude-3-5-sonnet