Gathering detailed insights and metrics for firestore-helper-ts
Gathering detailed insights and metrics for firestore-helper-ts
Gathering detailed insights and metrics for firestore-helper-ts
Gathering detailed insights and metrics for firestore-helper-ts
A simple library for working with Firebase Firestore in TypeScript/JavaScript applications
npm install firestore-helper-ts
Typescript
Module System
Node Version
NPM Version
TypeScript (95.4%)
JavaScript (4.32%)
Shell (0.28%)
Total Downloads
0
Last Day
0
Last Week
0
Last Month
0
Last Year
0
ISC License
2 Stars
30 Commits
1 Watchers
14 Branches
1 Contributors
Updated on Mar 16, 2025
Latest Version
1.8.0
Package Id
firestore-helper-ts@1.8.0
Unpacked Size
110.60 kB
Size
25.58 kB
File Count
40
NPM Version
10.8.2
Node Version
18.20.7
Published on
Mar 16, 2025
Cumulative downloads
Total Downloads
Last Day
0%
NaN
Compared to previous day
Last Week
0%
NaN
Compared to previous week
Last Month
0%
NaN
Compared to previous month
Last Year
0%
NaN
Compared to previous year
1
1
Simplify your work with Firestore and save dozens of coding hours! Firestore Helper TS solves common problems when working with Firestore:
Unlike direct use of the Firebase SDK, Firestore Helper significantly simplifies CRUD operations, provides a unified interface for working with data, and eliminates common sources of errors. Develop faster and more safely!
A simple and type-safe library for working with Firebase Firestore in TypeScript/JavaScript applications.
1# NPM 2npm install firestore-helper-ts 3 4# Yarn 5yarn add firestore-helper-ts 6 7# PNPM 8pnpm add firestore-helper-ts
1import { initialize } from "firestore-helper-ts"; 2 3// At the beginning of your application 4initialize({ 5 apiKey: "YOUR_API_KEY", 6 authDomain: "your-project.firebaseapp.com", 7 projectId: "your-project", 8 // other configuration... 9});
1import { create } from "firestore-helper-ts"; 2 3// Creates a document with automatically generated ID 4const result = await create({ 5 path: "users", // path to collection 6 data: { 7 name: "John Smith", 8 email: "john@example.com", 9 age: 32, 10 isActive: true, 11 }, 12}); 13 14// Creates a document with custom ID (e.g., UUID) 15const resultWithCustomId = await create({ 16 path: "users", 17 customId: "123e4567-e89b-12d3-a456-426614174000", // Your custom ID 18 data: { 19 name: "Jane Smith", 20 email: "jane@example.com", 21 age: 28, 22 isActive: true, 23 }, 24}); 25 26// You get back data including the ID in both cases 27const userId = result.data?.id; // Firestore generated ID 28const customUserId = resultWithCustomId.data?.id; // Your custom ID
1import { get } from "firestore-helper-ts"; 2 3// Get a single document 4const userResult = await get({ 5 path: "users", 6 docId: "abc123", // document ID 7}); 8 9if (userResult.data) { 10 console.log(`Name: ${userResult.data.name}`); 11} 12 13// Get an entire collection with filters and sorting 14const activeUsersResult = await get({ 15 path: "users", 16 where: [ 17 ["isActive", "==", true], // First filter 18 ["age", ">", 25], // Second filter 19 ], 20 orderBy: [ 21 ["createdAt", "desc"], // Sort by creation date descending 22 ], 23 limit: 10, // Limit number of results 24}); 25 26// Process results 27activeUsersResult.data?.forEach((user) => { 28 console.log(`${user.name} (${user.email})`); 29});
1import { update } from "firestore-helper-ts"; 2 3// Update document 4await update({ 5 path: "users", 6 docId: "abc123", 7 data: { 8 age: 33, 9 lastLogin: new Date(), 10 }, 11 merge: true, // Merge with existing data (default) 12 refetch: true, // Return updated data 13});
1import { removeDoc } from "firestore-helper-ts"; 2 3// Delete document 4await removeDoc({ 5 path: "users", 6 docId: "abc123", 7});
1import { listen } from "firestore-helper-ts"; 2 3// Listen to a single document 4const unsubscribe = listen({ 5 path: "users", 6 docId: "abc123", 7 onNext: (userData) => { 8 // Runs whenever the document changes 9 console.log("User data updated:", userData); 10 updateUI(userData); 11 }, 12 onError: (error) => { 13 console.error("Error listening to user:", error); 14 }, 15}); 16 17// Listen to a collection with filters 18const unsubscribeCollection = listen({ 19 path: "users", 20 where: [["isActive", "==", true]], 21 orderBy: [["lastActive", "desc"]], 22 limit: 10, 23 onNext: (users) => { 24 console.log("Active users updated:", users); 25 updateUsersList(users); 26 }, 27}); 28 29// Stop listening when no longer needed 30// For example when component unmounts 31unsubscribe(); 32unsubscribeCollection();
You can perform CRUD operations and immediately get real-time updates instead of a one-time fetch:
1import { create, update, removeDoc } from "firestore-helper-ts"; 2 3// Create a document and listen for changes 4const unsubscribeCreate = await create({ 5 path: "posts", 6 data: { 7 title: "New Post", 8 content: "Post content...", 9 createdAt: new Date(), 10 }, 11 useListener: true, // Enable real-time listening 12 onNext: (post) => { 13 console.log("Post created or updated:", post); 14 updateUI(post); 15 }, 16}); 17 18// Update a document and listen for changes 19const unsubscribeUpdate = await update({ 20 path: "posts", 21 docId: "post123", 22 data: { likes: 42 }, 23 useListener: true, 24 onNext: (post) => { 25 console.log("Post updated:", post); 26 updateUI(post); 27 }, 28}); 29 30// Later, stop listening 31unsubscribeCreate(); 32unsubscribeUpdate();
The library offers flexibility when importing functions:
1import { 2 getData, 3 updateData, 4 createData, 5 deleteData, 6 listenData, 7} from "firestore-helper-ts"; 8 9// Usage 10const result = await getData({ path: "users", docId: "abc123" });
1import { get, update, create, removeDoc, listen } from "firestore-helper-ts"; 2 3// Usage 4const result = await get({ path: "users", docId: "abc123" });
1import FirestoreHelper from "firestore-helper-ts"; 2 3// Usage 4const result = await FirestoreHelper.get({ path: "users", docId: "abc123" });
Check out the examples directory for usage examples with different frameworks:
For more details and instructions on running these examples, check the examples README.
Firestore Helper TS provides complete TypeScript support with generic types for all operations:
1// Define your data types 2interface User { 3 id?: string; 4 name: string; 5 email: string; 6 age: number; 7 isActive: boolean; 8 createdAt: Date; 9} 10 11interface Post { 12 id?: string; 13 title: string; 14 content: string; 15 authorId: string; 16 tags: string[]; 17 publishedAt?: Date; 18} 19 20// Use with CRUD operations 21const userResult = await get<User>({ 22 path: "users", 23 docId: "user123", 24}); 25 26const postsResult = await get<Post[]>({ 27 path: "posts", 28 where: [["authorId", "==", "user123"]], 29}); 30 31// Type-safe real-time listeners 32listen<User>({ 33 path: "users", 34 docId: "user123", 35 onNext: (user) => { 36 if (user) { 37 // TypeScript knows all available properties 38 console.log(`${user.name} (${user.email})`); 39 } 40 }, 41});
Firestore Helper TS includes a comprehensive error handling system that provides:
1import { 2 FirestoreHelperError, 3 ValidationError, 4 PermissionError, 5 NotFoundError, 6} from "firestore-helper-ts"; 7 8try { 9 const result = await get({ 10 path: "users", 11 docId: "user123", 12 }); 13 14 if (result.error) { 15 // Type-safe error handling 16 switch (result.error.constructor) { 17 case ValidationError: 18 console.error("Invalid parameters:", result.error.message); 19 break; 20 case PermissionError: 21 console.error("Permission denied:", result.error.message); 22 // Redirect to login 23 break; 24 case NotFoundError: 25 console.error("Document not found:", result.error.message); 26 // Show empty state 27 break; 28 default: 29 console.error("Unexpected error:", result.error.message); 30 } 31 } else { 32 // Process result.data 33 console.log("User data:", result.data); 34 } 35} catch (error) { 36 // Handle unexpected errors 37 console.error("Critical error:", error); 38}
ValidationError
: Invalid parameters or data formatPermissionError
: Insufficient permissionsNotFoundError
: Document or collection not foundInitializationError
: Firebase not properly initializedNetworkError
: Network-related issuesTimeoutError
: Operation timeoutCacheError
: Caching-related issuesFirestore Helper TS includes an intelligent caching system to optimize performance and reduce Firestore reads:
1import { configureCache, get } from "firestore-helper-ts"; 2 3// Configure global cache settings 4configureCache({ 5 enabled: true, // Enable/disable caching 6 maxSize: 1000, // Maximum number of cached items 7 ttl: 5 * 60 * 1000, // Time-to-live in milliseconds (5 minutes) 8}); 9 10// Use cache with get operations 11const result = await get({ 12 path: "users", 13 docId: "user123", 14 cache: { 15 enabled: true, // Enable for this request 16 ttl: 60000, // Custom TTL for this request (1 minute) 17 }, 18}); 19 20// Cache with collection queries 21const activeUsers = await get({ 22 path: "users", 23 where: [["isActive", "==", true]], 24 cache: { 25 enabled: true, 26 key: "active-users", // Custom cache key 27 }, 28}); 29 30// Clear cache for specific paths 31await clearCache("users/*"); 32 33// Clear all cache 34await clearCache(); 35 36// Get cache statistics 37const stats = getCacheStats(); 38console.log("Cache hits:", stats.hits); 39console.log("Cache misses:", stats.misses); 40console.log("Items in cache:", stats.size);
Firestore Helper TS includes a comprehensive logging system that helps you debug your application and understand what's happening under the hood.
The logging system supports various levels of detail:
1import { LogLevel, configureLogger } from "firestore-helper-ts"; 2 3// Available log levels 4LogLevel.NONE; // 0: No logging 5LogLevel.ERROR; // 1: Only errors (default) 6LogLevel.WARN; // 2: Errors and warnings 7LogLevel.INFO; // 3: Errors, warnings, and informational messages 8LogLevel.DEBUG; // 4: All messages including detailed debug info
To change the logging level:
1import { configureLogger, LogLevel } from "firestore-helper-ts"; 2 3// Enable all logs including debug 4configureLogger({ level: LogLevel.DEBUG }); 5 6// Only show errors and warnings 7configureLogger({ level: LogLevel.WARN }); 8 9// Disable all logging 10configureLogger({ level: LogLevel.NONE });
You can create dedicated loggers for different parts of your application:
1import { createLogger } from "firestore-helper-ts"; 2 3// Create loggers for different components 4const authLogger = createLogger("auth"); 5const dbLogger = createLogger("database"); 6const uiLogger = createLogger("ui"); 7 8// Use them in your code 9authLogger.info("User logged in successfully"); 10dbLogger.debug("Fetching data with params", { collection: "users", id: "123" }); 11uiLogger.warn("Component will be deprecated in next version");
You can customize how logs are formatted:
1// Configure timestamp and operation name display 2configureLogger({ 3 timestamps: true, // Include timestamps in logs 4 showOperation: true, // Include operation name in logs 5});
For production environments, you might want to send logs to a monitoring service:
1// Set up a custom handler for all logs 2configureLogger({ 3 level: LogLevel.ERROR, // Only process errors 4 customHandler: (level, message, ...data) => { 5 // Send to your logging service 6 myLoggingService.capture({ 7 level: LogLevel[level], 8 message, 9 data, 10 timestamp: new Date().toISOString(), 11 }); 12 }, 13});
In development, enable detailed logging to see what's happening:
1// During development 2configureLogger({ level: LogLevel.DEBUG }); 3 4// Later in production 5configureLogger({ level: LogLevel.ERROR });
For a complete example of using the logging system, check examples/logging-example.ts.
1import { 2 initialize, 3 get, 4 create, 5 update, 6 removeDoc, 7 listen, 8 Result, 9} from "firestore-helper-ts"; 10 11// Type definitions 12interface Product { 13 id?: string; 14 name: string; 15 price: number; 16 stock: number; 17 categories: string[]; 18} 19 20// Initialize Firebase 21initialize({ 22 /* configuration */ 23}); 24 25// Create product 26async function createProduct( 27 productData: Omit<Product, "id"> 28): Promise<string | null> { 29 const result = await create<Product>({ 30 path: "products", 31 data: productData, 32 }); 33 34 return result.data?.id || null; 35} 36 37// Get product by ID 38async function getProduct(productId: string): Promise<Product | null> { 39 const result = await get<Product>({ 40 path: "products", 41 docId: productId, 42 }); 43 44 return result.data; 45} 46 47// Get products by category 48async function getProductsByCategory(category: string): Promise<Product[]> { 49 const result = await get<Product[]>({ 50 path: "products", 51 where: [["categories", "array-contains", category]], 52 orderBy: [["price", "asc"]], 53 }); 54 55 return result.data || []; 56} 57 58// Update stock 59async function updateStock( 60 productId: string, 61 newStock: number 62): Promise<boolean> { 63 const result = await update({ 64 path: "products", 65 docId: productId, 66 data: { stock: newStock }, 67 }); 68 69 return !result.error; 70} 71 72// Delete product 73async function deleteProduct(productId: string): Promise<boolean> { 74 const result = await removeDoc({ 75 path: "products", 76 docId: productId, 77 }); 78 79 return !result.error; 80} 81 82// Listen to stock changes 83function listenToStockChanges( 84 productId: string, 85 callback: (stock: number) => void 86): () => void { 87 return listen<Product>({ 88 path: "products", 89 docId: productId, 90 onNext: (product) => { 91 if (product) { 92 callback(product.stock); 93 } 94 }, 95 }); 96} 97 98// Using the functions 99async function manageInventory() { 100 // Create product 101 const newProductId = await createProduct({ 102 name: "Smartphone", 103 price: 699.99, 104 stock: 10, 105 categories: ["electronics", "phones"], 106 }); 107 108 // Get product 109 const product = await getProduct(newProductId!); 110 console.log(`Product: ${product?.name}, Price: $${product?.price}`); 111 112 // Update stock 113 await updateStock(newProductId!, 8); 114 115 // Get products by category 116 const phones = await getProductsByCategory("phones"); 117 console.log(`Found ${phones.length} phones`); 118 119 // Set up real-time listener for stock changes 120 const unsubscribe = listenToStockChanges(newProductId!, (newStock) => { 121 console.log(`Stock changed: ${newStock} units available`); 122 updateStockDisplay(newStock); 123 }); 124 125 // Later, when no longer needed 126 unsubscribe(); 127 128 // Delete product 129 await deleteProduct(newProductId!); 130}
1import { get } from "firestore-helper-ts"; 2 3// Find active premium users who have logged in recently 4const result = await get({ 5 path: "users", 6 where: [ 7 ["isActive", "==", true], 8 ["subscriptionTier", "==", "premium"], 9 ["lastLogin", ">", new Date(Date.now() - 7 * 24 * 60 * 60 * 1000)], // 7 days ago 10 ], 11 orderBy: [ 12 ["lastLogin", "desc"], // Most recent logins first 13 ], 14 limit: 20, 15}); 16 17// Process the results 18result.data?.forEach((user) => { 19 console.log( 20 `Premium user ${user.name} last logged in on ${user.lastLogin.toDate()}` 21 ); 22});
1import { create, get, update, listen } from "firestore-helper-ts"; 2 3// Create a parent document 4const { data: organization } = await create({ 5 path: "organizations", 6 data: { name: "Acme Inc.", founded: 1985 }, 7}); 8 9// Add a document to a subcollection 10const orgId = organization.id; 11await create({ 12 path: `organizations/${orgId}/departments`, 13 data: { name: "Engineering", headCount: 25 }, 14}); 15 16// Get all departments for an organization 17const { data: departments } = await get({ 18 path: `organizations/${orgId}/departments`, 19}); 20 21// Listen to changes in departments 22const unsubscribe = listen({ 23 path: `organizations/${orgId}/departments`, 24 onNext: (departments) => { 25 console.log("Departments updated:", departments); 26 updateDepartmentsList(departments); 27 }, 28});
1import { listen } from "firestore-helper-ts"; 2 3function setupDashboard() { 4 // Listen to active orders 5 const unsubscribeOrders = listen({ 6 path: "orders", 7 where: [["status", "==", "active"]], 8 orderBy: [["createdAt", "desc"]], 9 onNext: (orders) => { 10 updateOrdersDisplay(orders); 11 12 // Calculate total revenue 13 const totalRevenue = orders.reduce((sum, order) => sum + order.total, 0); 14 updateRevenueDisplay(totalRevenue); 15 }, 16 }); 17 18 // Listen to inventory levels 19 const unsubscribeInventory = listen({ 20 path: "products", 21 where: [["stock", "<", 10]], // Low stock items 22 onNext: (lowStockProducts) => { 23 updateLowStockAlerts(lowStockProducts); 24 }, 25 }); 26 27 // Listen to new user registrations 28 const unsubscribeUsers = listen({ 29 path: "users", 30 orderBy: [["createdAt", "desc"]], 31 limit: 5, 32 onNext: (recentUsers) => { 33 updateRecentUsersWidget(recentUsers); 34 }, 35 }); 36 37 // Return a function to unsubscribe from all listeners 38 return () => { 39 unsubscribeOrders(); 40 unsubscribeInventory(); 41 unsubscribeUsers(); 42 }; 43} 44 45// In a React component: 46// useEffect(() => { 47// const unsubscribeAll = setupDashboard(); 48// return () => unsubscribeAll(); 49// }, []);
You can use your own document IDs (like UUID) when creating documents:
1import { v4 as uuidv4 } from "uuid"; 2import { create } from "firestore-helper-ts"; 3 4// Create a document with UUID 5const result = await create({ 6 path: "users", 7 customId: uuidv4(), // Use UUID as document ID 8 data: { 9 name: "John Doe", 10 email: "john@example.com", 11 }, 12}); 13 14// The document will be created with your custom ID 15console.log("Created user with custom ID:", result.data?.id);
This is useful when:
Check out our examples directory for complete working examples:
basic.ts
- Basic CRUD operationstypescript-example.ts
- TypeScript integrationerror-handling-example.ts
- Error handling patternscaching-example.ts
- Caching implementationreal-time-example.ts
- Real-time listenersWe provide examples for popular frameworks:
react-example.tsx
nextjs-example.tsx
vue-example.ts
The library contains unit tests to ensure proper functionality. Tests are written using the Jest framework.
1# Run all tests 2npm test 3 4# Run tests with watch mode 5npm run test:watch 6 7# Run tests with code coverage 8npm run test:coverage
This repository uses GitHub Actions to automate the development, testing, and release process.
ISC
No vulnerabilities found.
No security vulnerabilities found.