Learn how to create, read, update, and delete documents using FirestoreORM
FirestoreORM provides a clean, type-safe API for all basic database operations. This guide covers creating, reading, updating, and deleting documents with practical examples.
Lifecycle hooks allow you to run custom logic before or after creation.
// Send welcome email after user creationuserRepo.on('afterCreate', async (user) => { await sendWelcomeEmail(user.email); console.log(`Welcome email sent to ${user.email}`);});// Validate business rules before creationuserRepo.on('beforeCreate', (user) => { if (user.email.endsWith('@competitor.com')) { throw new Error('Cannot create user with competitor email'); }});const user = await userRepo.create({ name: 'Jane Smith', email: '[email protected]'});// Hooks execute automatically
// Find all users with a specific emailconst users = await userRepo.findByField('email', '[email protected]');// Find all orders with status 'pending'const pendingOrders = await orderRepo.findByField('status', 'pending');
// Get first 20 usersconst firstPage = await userRepo.list(20);// Get next 20 users (pass the last ID from previous page)const lastId = firstPage[firstPage.length - 1]?.id;const nextPage = await userRepo.list(20, lastId);// Include soft-deleted documentsconst allUsers = await userRepo.list(50, undefined, true);
For large datasets, use the query builder’s pagination methods instead of list() for better performance.
Mark documents as deleted without removing them from Firestore.
// Soft delete - document stays in databaseawait userRepo.softDelete('user-123');// Document is excluded from queries by defaultconst user = await userRepo.getById('user-123'); // null// But can be retrieved with includeDeleted flagconst deletedUser = await userRepo.getById('user-123', true);console.log(deletedUser.deletedAt); // '2024-01-15T10:30:00.000Z'
1
Soft Delete
Call softDelete() to mark the document with a deletedAt timestamp.
2
Document Hidden
The document is automatically excluded from all queries.
3
Restore if Needed
You can restore the document later using restore().
// Restore a single documentawait userRepo.restore('user-123');// Document is now accessible in queries againconst user = await userRepo.getById('user-123');console.log(user.deletedAt); // null// Restore all soft-deleted documents in collectionconst restoredCount = await userRepo.restoreAll();console.log(`Restored ${restoredCount} users`);
Include createdAt and updatedAt fields in your schema and update them consistently.
await userRepo.create({ ...data, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString()});await userRepo.update(id, { ...data, updatedAt: new Date().toISOString()});
2
Use Soft Deletes
Default to soft deletes to maintain data integrity and enable recovery.
// ✅ Good - recoverableawait userRepo.softDelete(userId);// ❌ Use sparingly - permanentawait userRepo.delete(userId);
3
Validate with Zod Schemas
Always use schema validation to catch errors before they reach Firestore.