@umituz/react-native-firebase 1.13.58 → 1.13.60
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +277 -0
- package/package.json +10 -5
- package/scripts/README.md +513 -0
- package/src/auth/README.md +339 -0
- package/src/auth/domain/README.md +264 -0
- package/src/auth/domain/errors/README.md +291 -0
- package/src/auth/infrastructure/config/README.md +239 -0
- package/src/auth/infrastructure/config/initializers/FirebaseAuthInitializer.ts +1 -1
- package/src/auth/infrastructure/services/README.md +346 -0
- package/src/auth/infrastructure/stores/README.md +407 -0
- package/src/auth/infrastructure/stores/auth.store.ts +1 -1
- package/src/auth/presentation/hooks/README.md +442 -0
- package/src/auth/presentation/hooks/useAnonymousAuth.ts +4 -4
- package/src/auth/presentation/hooks/utils/auth-state-change.handler.ts +1 -1
- package/src/domain/README.md +628 -0
- package/src/firestore/README.md +566 -0
- package/src/firestore/domain/README.md +325 -0
- package/src/firestore/domain/constants/README.md +332 -0
- package/src/firestore/domain/entities/README.md +286 -0
- package/src/firestore/domain/errors/README.md +389 -0
- package/src/firestore/infrastructure/config/FirestoreClient.ts +1 -1
- package/src/firestore/infrastructure/config/README.md +239 -0
- package/src/firestore/infrastructure/middleware/README.md +316 -0
- package/src/firestore/infrastructure/repositories/BaseRepository.ts +1 -1
- package/src/firestore/infrastructure/repositories/README.md +425 -0
- package/src/firestore/infrastructure/services/README.md +332 -0
- package/src/firestore/infrastructure/services/RequestLoggerService.ts +4 -4
- package/src/firestore/types/pagination/README.md +332 -0
- package/src/firestore/utils/README.md +574 -0
- package/src/firestore/utils/dateUtils/README.md +171 -0
- package/src/firestore/utils/document-mapper.helper/README.md +309 -0
- package/src/firestore/utils/pagination.helper/README.md +298 -0
- package/src/firestore/utils/path-resolver/README.md +277 -0
- package/src/firestore/utils/query-builder/README.md +291 -0
- package/src/firestore/utils/quota-error-detector/README.md +355 -0
- package/src/infrastructure/README.md +408 -0
- package/src/infrastructure/config/FirebaseClient.ts +1 -1
- package/src/infrastructure/config/README.md +262 -0
- package/src/presentation/README.md +556 -0
- package/src/storage/README.md +493 -0
- package/src/storage/deleter/README.md +370 -0
- package/src/storage/types/README.md +313 -0
- package/src/storage/uploader/README.md +409 -0
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
# Request Logger Service
|
|
2
|
+
|
|
3
|
+
Service for logging and tracking Firestore requests with statistics and analytics.
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
Provides comprehensive logging capabilities for Firestore operations including request tracking, statistics calculation, query hashing, log export, and analytics.
|
|
8
|
+
|
|
9
|
+
## For AI Agents
|
|
10
|
+
|
|
11
|
+
### Before Using Request Logger
|
|
12
|
+
|
|
13
|
+
1. **LOG** all Firestore operations for monitoring
|
|
14
|
+
2. **TRACK** quota usage with request logs
|
|
15
|
+
3. **CALCULATE** statistics from logs
|
|
16
|
+
4. **EXPORT** logs for analysis
|
|
17
|
+
5. **CLEANUP** old logs regularly
|
|
18
|
+
|
|
19
|
+
### Required Practices
|
|
20
|
+
|
|
21
|
+
1. **Log all operations** - Log every Firestore operation
|
|
22
|
+
2. **Use RequestLog type** - Type-safe log entries
|
|
23
|
+
3. **Calculate statistics** - Use getStats() method
|
|
24
|
+
4. **Export logs** - Export for offline analysis
|
|
25
|
+
5. **Clean up old logs** - Remove logs periodically
|
|
26
|
+
|
|
27
|
+
### Forbidden Practices
|
|
28
|
+
|
|
29
|
+
## ❌ NEVER
|
|
30
|
+
|
|
31
|
+
- Log sensitive user data in requests
|
|
32
|
+
- Log request payloads or document content
|
|
33
|
+
- Store logs indefinitely without cleanup
|
|
34
|
+
- Log in production database (use external service)
|
|
35
|
+
- Ignore logging for debugging
|
|
36
|
+
|
|
37
|
+
## ⚠️ Avoid
|
|
38
|
+
|
|
39
|
+
- Logging every single read operation (use sampling)
|
|
40
|
+
- Not cleaning up old logs
|
|
41
|
+
- Logging in production without monitoring
|
|
42
|
+
- Complex logging logic in critical path
|
|
43
|
+
- Storing logs in production database
|
|
44
|
+
|
|
45
|
+
## Service Methods
|
|
46
|
+
|
|
47
|
+
### logRequest
|
|
48
|
+
|
|
49
|
+
**Import From:** `@umituz/react-native-firebase/firestore` or `src/firestore/infrastructure/services`
|
|
50
|
+
|
|
51
|
+
**Purpose:** Log a Firestore operation
|
|
52
|
+
|
|
53
|
+
**Parameters:** `RequestLog` object
|
|
54
|
+
- `type: RequestType` - Operation type ('read', 'write', 'delete')
|
|
55
|
+
- `collectionName: string` - Collection being accessed
|
|
56
|
+
- `documentCount: number` - Number of documents affected
|
|
57
|
+
- `timestamp: number` - Unix timestamp
|
|
58
|
+
- `queryHash?: string` - Hash for duplicate detection
|
|
59
|
+
|
|
60
|
+
**Returns:** `void`
|
|
61
|
+
|
|
62
|
+
**Usage Strategy:**
|
|
63
|
+
1. Create RequestLog before operation
|
|
64
|
+
2. Call logRequest() with log data
|
|
65
|
+
3. Include queryHash for duplicates
|
|
66
|
+
4. Log after operation completes
|
|
67
|
+
5. Handle errors appropriately
|
|
68
|
+
|
|
69
|
+
**When to Use:**
|
|
70
|
+
- All repository read operations
|
|
71
|
+
- All repository write operations
|
|
72
|
+
- All repository delete operations
|
|
73
|
+
- Quota tracking
|
|
74
|
+
- Performance monitoring
|
|
75
|
+
|
|
76
|
+
### getLogs
|
|
77
|
+
|
|
78
|
+
**Import From:** `@umituz/react-native-firebase/firestore` or `src/firestore/infrastructure/services`
|
|
79
|
+
|
|
80
|
+
**Purpose:** Retrieve all logged requests
|
|
81
|
+
|
|
82
|
+
**Returns:** `RequestLog[]` - Array of all log entries
|
|
83
|
+
|
|
84
|
+
**Usage Strategy:**
|
|
85
|
+
1. Call getLogs() to retrieve logs
|
|
86
|
+
2. Analyze log patterns
|
|
87
|
+
3. Calculate statistics
|
|
88
|
+
4. Export for analysis
|
|
89
|
+
5. Display to users if needed
|
|
90
|
+
|
|
91
|
+
**When to Use:**
|
|
92
|
+
- Analyzing usage patterns
|
|
93
|
+
- Calculating statistics
|
|
94
|
+
- Exporting logs
|
|
95
|
+
- Debugging issues
|
|
96
|
+
- Monitoring quota
|
|
97
|
+
|
|
98
|
+
### getStats
|
|
99
|
+
|
|
100
|
+
**Import From:** `@umituz/react-native-firebase/firestore` or `src/firestore/infrastructure/services`
|
|
101
|
+
|
|
102
|
+
**Purpose:** Calculate usage statistics from logs
|
|
103
|
+
|
|
104
|
+
**Returns:** `RequestStats` object
|
|
105
|
+
- `totalReads: number` - Total read operations
|
|
106
|
+
- `totalWrites: number` - Total write operations
|
|
107
|
+
- `totalDeletes: number` - Total delete operations
|
|
108
|
+
- `totalRequests: number` - Total all operations
|
|
109
|
+
- `avgDocCount: number` - Average documents per request
|
|
110
|
+
|
|
111
|
+
**Usage Strategy:**
|
|
112
|
+
1. Call getStats() to calculate statistics
|
|
113
|
+
2. Display statistics to users
|
|
114
|
+
3. Check quota usage
|
|
115
|
+
4. Monitor trends
|
|
116
|
+
5. Generate reports
|
|
117
|
+
|
|
118
|
+
**When to Use:**
|
|
119
|
+
- Displaying quota usage
|
|
120
|
+
- Monitoring performance
|
|
121
|
+
- Cost analysis
|
|
122
|
+
- Usage trends
|
|
123
|
+
- Before large operations
|
|
124
|
+
|
|
125
|
+
### clearLogs
|
|
126
|
+
|
|
127
|
+
**Import From:** `@umituz/react-native-firebase/firestore` or `src/firestore/infrastructure/services`
|
|
128
|
+
|
|
129
|
+
**Purpose:** Remove all logged requests
|
|
130
|
+
|
|
131
|
+
**Returns:** `void`
|
|
132
|
+
|
|
133
|
+
**Usage Strategy:**
|
|
134
|
+
1. Export logs before clearing
|
|
135
|
+
2. Call clearLogs() to reset
|
|
136
|
+
3. Schedule periodic cleanup
|
|
137
|
+
4. Clear after exporting
|
|
138
|
+
5. Confirm before clearing
|
|
139
|
+
|
|
140
|
+
**When to Use:**
|
|
141
|
+
- Periodic log cleanup
|
|
142
|
+
- After exporting logs
|
|
143
|
+
- Free up memory
|
|
144
|
+
- Start fresh tracking
|
|
145
|
+
- Privacy requirements
|
|
146
|
+
|
|
147
|
+
## Usage Strategies
|
|
148
|
+
|
|
149
|
+
### For Quota Tracking
|
|
150
|
+
|
|
151
|
+
**Strategy:** Use request logs to track Firestore quota usage.
|
|
152
|
+
|
|
153
|
+
**Import From:** `@umituz/react-native-firebase/firestore` or `src/firestore/infrastructure/services`
|
|
154
|
+
|
|
155
|
+
**When to Use:**
|
|
156
|
+
- Monitoring quota consumption
|
|
157
|
+
- Warning threshold detection
|
|
158
|
+
- Usage analytics
|
|
159
|
+
- Cost optimization
|
|
160
|
+
|
|
161
|
+
**Tracking Metrics:**
|
|
162
|
+
- Total read operations
|
|
163
|
+
- Total write operations
|
|
164
|
+
- Total delete operations
|
|
165
|
+
- Average document count per request
|
|
166
|
+
- Request rate over time
|
|
167
|
+
|
|
168
|
+
**Implementation:**
|
|
169
|
+
1. Log all Firestore operations
|
|
170
|
+
2. Calculate statistics periodically
|
|
171
|
+
3. Check quota thresholds
|
|
172
|
+
4. Display usage to users
|
|
173
|
+
5. Warn when approaching limits
|
|
174
|
+
|
|
175
|
+
### For Analytics
|
|
176
|
+
|
|
177
|
+
**Strategy:** Analyze request logs for performance insights.
|
|
178
|
+
|
|
179
|
+
**Import From:** `@umituz/react-native-firebase/firestore` or `src/firestore/infrastructure/services`
|
|
180
|
+
|
|
181
|
+
**When to Use:**
|
|
182
|
+
- Performance monitoring
|
|
183
|
+
- Query optimization
|
|
184
|
+
- Usage patterns analysis
|
|
185
|
+
- Cost optimization
|
|
186
|
+
|
|
187
|
+
**Analytics Metrics:**
|
|
188
|
+
- Most queried collections
|
|
189
|
+
- Average document counts
|
|
190
|
+
- Request frequency
|
|
191
|
+
- Query patterns (via queryHash)
|
|
192
|
+
|
|
193
|
+
**Implementation:**
|
|
194
|
+
1. Collect logs over time period
|
|
195
|
+
2. Analyze collection access patterns
|
|
196
|
+
3. Identify heavy queries
|
|
197
|
+
4. Optimize based on findings
|
|
198
|
+
5. Generate reports
|
|
199
|
+
|
|
200
|
+
### For Debugging
|
|
201
|
+
|
|
202
|
+
**Strategy:** Use request logs to debug Firestore operations.
|
|
203
|
+
|
|
204
|
+
**Import From:** `@umituz/react-native-firebase/firestore` or `src/firestore/infrastructure/services`
|
|
205
|
+
|
|
206
|
+
**When to Use:**
|
|
207
|
+
- Investigating performance issues
|
|
208
|
+
- Debugging quota spikes
|
|
209
|
+
- Identifying problematic queries
|
|
210
|
+
- Tracking operation failures
|
|
211
|
+
|
|
212
|
+
**Debugging Approach:**
|
|
213
|
+
1. Enable request logging
|
|
214
|
+
2. Reproduce issue
|
|
215
|
+
3. Review logs for operations
|
|
216
|
+
4. Identify problematic patterns
|
|
217
|
+
5. Fix and verify
|
|
218
|
+
|
|
219
|
+
## Common Mistakes to Avoid
|
|
220
|
+
|
|
221
|
+
1. ❌ Logging sensitive user data
|
|
222
|
+
- ✅ Only log operation metadata
|
|
223
|
+
|
|
224
|
+
2. ❌ Not logging all operations
|
|
225
|
+
- ✅ Log every Firestore operation
|
|
226
|
+
|
|
227
|
+
3. ❌ Storing logs indefinitely
|
|
228
|
+
- ✅ Clean up old logs regularly
|
|
229
|
+
|
|
230
|
+
4. ❌ Not using types
|
|
231
|
+
- ✅ Always use RequestLog type
|
|
232
|
+
|
|
233
|
+
5. ❌ Logging in production database
|
|
234
|
+
- ✅ Use external logging service
|
|
235
|
+
|
|
236
|
+
## AI Agent Instructions
|
|
237
|
+
|
|
238
|
+
### When Logging Requests
|
|
239
|
+
|
|
240
|
+
1. Create RequestLog before operation
|
|
241
|
+
2. Populate all required fields
|
|
242
|
+
3. Include queryHash for duplicates
|
|
243
|
+
4. Call logRequest() method
|
|
244
|
+
5. Handle errors appropriately
|
|
245
|
+
|
|
246
|
+
### When Calculating Statistics
|
|
247
|
+
|
|
248
|
+
1. Collect logs over time period
|
|
249
|
+
2. Call getStats() method
|
|
250
|
+
3. Display statistics appropriately
|
|
251
|
+
4. Check quota thresholds
|
|
252
|
+
5. Generate reports
|
|
253
|
+
|
|
254
|
+
### When Exporting Logs
|
|
255
|
+
|
|
256
|
+
1. Call getLogs() to retrieve
|
|
257
|
+
2. Export to CSV/JSON
|
|
258
|
+
3. Store externally (not in database)
|
|
259
|
+
4. Clear logs after export
|
|
260
|
+
5. Schedule regular exports
|
|
261
|
+
|
|
262
|
+
## Code Quality Standards
|
|
263
|
+
|
|
264
|
+
### TypeScript
|
|
265
|
+
|
|
266
|
+
- Use RequestLog type for all logs
|
|
267
|
+
- Use RequestType for operation types
|
|
268
|
+
- Type all method parameters
|
|
269
|
+
- Type all return values
|
|
270
|
+
- Export types for use in other modules
|
|
271
|
+
|
|
272
|
+
### Error Handling
|
|
273
|
+
|
|
274
|
+
- Wrap logging in try-catch
|
|
275
|
+
- Don't let logging break operations
|
|
276
|
+
- Log logging failures
|
|
277
|
+
- Handle edge cases
|
|
278
|
+
- Test error scenarios
|
|
279
|
+
|
|
280
|
+
## Performance Considerations
|
|
281
|
+
|
|
282
|
+
### Logging Overhead
|
|
283
|
+
|
|
284
|
+
- Minimal performance impact
|
|
285
|
+
- In-memory logging (fast)
|
|
286
|
+
- Type checking at compile time
|
|
287
|
+
- No network calls
|
|
288
|
+
- Acceptable for all operations
|
|
289
|
+
|
|
290
|
+
### Storage Strategy
|
|
291
|
+
|
|
292
|
+
**Don't Store in Production Database:**
|
|
293
|
+
- Use external logging service
|
|
294
|
+
- Export logs for analysis
|
|
295
|
+
- Keep logs in memory temporarily
|
|
296
|
+
- Aggregate before storage
|
|
297
|
+
- Clean up regularly
|
|
298
|
+
|
|
299
|
+
### Log Cleanup
|
|
300
|
+
|
|
301
|
+
**Regular Cleanup:**
|
|
302
|
+
- Remove logs older than retention period
|
|
303
|
+
- Aggregate before deletion
|
|
304
|
+
- Keep statistics for long-term
|
|
305
|
+
- Compress old logs if needed
|
|
306
|
+
- Schedule automatic cleanup
|
|
307
|
+
|
|
308
|
+
## Related Documentation
|
|
309
|
+
|
|
310
|
+
- [Firestore Module README](../../README.md)
|
|
311
|
+
- [Request Log Types README](../../domain/entities/README.md)
|
|
312
|
+
- [Quota Tracking README](../middleware/README.md)
|
|
313
|
+
|
|
314
|
+
## API Reference
|
|
315
|
+
|
|
316
|
+
### Main Service
|
|
317
|
+
|
|
318
|
+
**Import Path:** `@umituz/react-native-firebase/firestore` or `src/firestore/infrastructure/services`
|
|
319
|
+
|
|
320
|
+
**Service:** `requestLoggerService`
|
|
321
|
+
|
|
322
|
+
| Method | Parameters | Returns | Description |
|
|
323
|
+
|--------|-----------|---------|-------------|
|
|
324
|
+
| `logRequest` | `RequestLog` | `void` | Log a Firestore operation |
|
|
325
|
+
| `getLogs` | - | `RequestLog[]` | Get all logged requests |
|
|
326
|
+
| `getStats` | - | `RequestStats` | Calculate usage statistics |
|
|
327
|
+
| `clearLogs` | - | `void` | Clear all logged requests |
|
|
328
|
+
|
|
329
|
+
---
|
|
330
|
+
|
|
331
|
+
**Last Updated:** 2025-01-08
|
|
332
|
+
**Maintainer:** Firestore Module Team
|
|
@@ -36,10 +36,10 @@ export class RequestLoggerService {
|
|
|
36
36
|
: fullLog.collection;
|
|
37
37
|
|
|
38
38
|
if (fullLog.success) {
|
|
39
|
-
|
|
39
|
+
|
|
40
40
|
console.log(`${prefix} ${status} ${operation}: ${details}`);
|
|
41
41
|
} else {
|
|
42
|
-
|
|
42
|
+
|
|
43
43
|
console.error(`${prefix} ${status} ${operation}: ${details}`, fullLog.error);
|
|
44
44
|
}
|
|
45
45
|
}
|
|
@@ -125,9 +125,9 @@ export class RequestLoggerService {
|
|
|
125
125
|
try {
|
|
126
126
|
listener(log);
|
|
127
127
|
} catch (error) {
|
|
128
|
-
|
|
128
|
+
|
|
129
129
|
if (__DEV__) {
|
|
130
|
-
|
|
130
|
+
|
|
131
131
|
console.error('[RequestLogger] Listener error:', error);
|
|
132
132
|
}
|
|
133
133
|
}
|
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
# Pagination Types
|
|
2
|
+
|
|
3
|
+
TypeScript types and interfaces for Firestore pagination operations.
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
Provides type-safe pagination structures for cursor-based pagination in Firestore queries, ensuring consistent pagination patterns across the application.
|
|
8
|
+
|
|
9
|
+
## For AI Agents
|
|
10
|
+
|
|
11
|
+
### Before Using Pagination Types
|
|
12
|
+
|
|
13
|
+
1. **UNDERSTAND** cursor-based pagination (not offset-based)
|
|
14
|
+
2. **USE** these types for all paginated queries
|
|
15
|
+
3. **NEVER** mix with offset-based pagination
|
|
16
|
+
4. **ALWAYS** fetch limit + 1 for hasMore detection
|
|
17
|
+
5. **STORE** cursor for next page in UI state
|
|
18
|
+
|
|
19
|
+
### Required Practices
|
|
20
|
+
|
|
21
|
+
1. **Use PaginatedResult<T>** for all paginated query returns
|
|
22
|
+
2. **Use PaginationParams** for all paginated query inputs
|
|
23
|
+
3. **Fetch limit + 1** to detect if more pages exist
|
|
24
|
+
4. **Store nextCursor** in UI state for subsequent requests
|
|
25
|
+
5. **Handle empty results** with EMPTY_PAGINATED_RESULT
|
|
26
|
+
|
|
27
|
+
### Forbidden Practices
|
|
28
|
+
|
|
29
|
+
## ❌ NEVER
|
|
30
|
+
|
|
31
|
+
- Use offset-based pagination (skip/take) - not scalable
|
|
32
|
+
- Fetch exactly limit items (can't detect hasMore)
|
|
33
|
+
- Mix cursor and offset pagination
|
|
34
|
+
- Ignore nextCursor (breaks pagination)
|
|
35
|
+
- Use pagination for small datasets (< 100 items)
|
|
36
|
+
|
|
37
|
+
## ⚠️ Avoid
|
|
38
|
+
|
|
39
|
+
- Complex cursor extraction logic
|
|
40
|
+
- Storing entire paginated result in state (only cursor needed)
|
|
41
|
+
- Not handling last page correctly
|
|
42
|
+
- Infinite loops in pagination
|
|
43
|
+
- Inconsistent page sizes
|
|
44
|
+
|
|
45
|
+
## Usage Strategies
|
|
46
|
+
|
|
47
|
+
### For Repository Methods
|
|
48
|
+
|
|
49
|
+
**Strategy:** Return PaginatedResult from repository query methods.
|
|
50
|
+
|
|
51
|
+
**Import From:** `src/firestore/types/pagination`
|
|
52
|
+
|
|
53
|
+
**When to Use:**
|
|
54
|
+
- Large datasets (> 100 documents)
|
|
55
|
+
- Infinite scroll implementations
|
|
56
|
+
- Ordered result sets requiring pagination
|
|
57
|
+
- Mobile applications (performance)
|
|
58
|
+
|
|
59
|
+
**Repository Pattern:**
|
|
60
|
+
1. Accept `PaginationParams` as parameter
|
|
61
|
+
2. Fetch `limit + 1` documents
|
|
62
|
+
3. Build PaginatedResult from fetched items
|
|
63
|
+
4. Set `hasMore: true` if items.length > limit
|
|
64
|
+
5. Set `nextCursor` from last visible item
|
|
65
|
+
|
|
66
|
+
**Type Safety:**
|
|
67
|
+
- Use generic type `PaginatedResult<EntityType>`
|
|
68
|
+
- TypeScript ensures type consistency
|
|
69
|
+
- Autocomplete for result properties
|
|
70
|
+
|
|
71
|
+
### For UI Components
|
|
72
|
+
|
|
73
|
+
**Strategy:** Store cursor in state, load next page on demand.
|
|
74
|
+
|
|
75
|
+
**Import From:** `src/firestore/types/pagination`
|
|
76
|
+
|
|
77
|
+
**State Management:**
|
|
78
|
+
- Store `data: T[]` in state
|
|
79
|
+
- Store `hasMore: boolean` in state
|
|
80
|
+
- Store `nextCursor?: string` in state
|
|
81
|
+
- Load more when user reaches end
|
|
82
|
+
|
|
83
|
+
**Pagination Flow:**
|
|
84
|
+
1. Initial load: Call with `{ pageSize: 20 }`
|
|
85
|
+
2. Append results to state
|
|
86
|
+
3. Store nextCursor if hasMore is true
|
|
87
|
+
4. On scroll end: Call with `{ pageSize: 20, cursor }`
|
|
88
|
+
5. Stop when hasMore is false
|
|
89
|
+
|
|
90
|
+
### For React Hooks
|
|
91
|
+
|
|
92
|
+
**Strategy:** Create custom hook for pagination state management.
|
|
93
|
+
|
|
94
|
+
**Import From:** `src/firestore/types/pagination`
|
|
95
|
+
|
|
96
|
+
**Hook Responsibilities:**
|
|
97
|
+
- Manage pagination state
|
|
98
|
+
- Provide loadMore function
|
|
99
|
+
- Handle loading states
|
|
100
|
+
- Reset pagination when needed
|
|
101
|
+
|
|
102
|
+
**Hook State:**
|
|
103
|
+
- `data` - Accumulated items across pages
|
|
104
|
+
- `hasMore` - Whether more pages exist
|
|
105
|
+
- `loading` - Current page loading state
|
|
106
|
+
- `error` - Any error from last fetch
|
|
107
|
+
|
|
108
|
+
**Hook Methods:**
|
|
109
|
+
- `loadMore()` - Fetch next page
|
|
110
|
+
- `refresh()` - Reset and reload
|
|
111
|
+
- `hasNextPage()` - Check if can load more
|
|
112
|
+
|
|
113
|
+
## Type Definitions
|
|
114
|
+
|
|
115
|
+
### PaginationParams
|
|
116
|
+
|
|
117
|
+
**Import From:** `src/firestore/types/pagination`
|
|
118
|
+
|
|
119
|
+
**Properties:**
|
|
120
|
+
- `pageSize?: number` - Items per page (default: 20)
|
|
121
|
+
- `cursor?: string` - Cursor from previous page's last item
|
|
122
|
+
|
|
123
|
+
**Usage:**
|
|
124
|
+
- Pass to repository `paginate()` method
|
|
125
|
+
- Include cursor for page 2+
|
|
126
|
+
- Omit cursor for first page
|
|
127
|
+
|
|
128
|
+
### PaginatedResult<T>
|
|
129
|
+
|
|
130
|
+
**Import From:** `src/firestore/types/pagination`
|
|
131
|
+
|
|
132
|
+
**Generic Type:** `<T>` - Type of items in data array
|
|
133
|
+
|
|
134
|
+
**Properties:**
|
|
135
|
+
- `data: T[]` - Items for current page
|
|
136
|
+
- `hasMore: boolean` - Whether more pages exist
|
|
137
|
+
- `nextCursor?: string` - Cursor for next page (null if no more)
|
|
138
|
+
- `totalCount?: number` - Total count (optional, rarely used)
|
|
139
|
+
|
|
140
|
+
**Usage:**
|
|
141
|
+
- Return type for repository paginate methods
|
|
142
|
+
- Type-safe with generic parameter
|
|
143
|
+
- TypeScript knows item types
|
|
144
|
+
|
|
145
|
+
### EMPTY_PAGINATED_RESULT
|
|
146
|
+
|
|
147
|
+
**Import From:** `src/firestore/types/pagination`
|
|
148
|
+
|
|
149
|
+
**Type:** `PaginatedResult<never>`
|
|
150
|
+
|
|
151
|
+
**Value:**
|
|
152
|
+
- `data: []` - Empty array
|
|
153
|
+
- `hasMore: false` - No more pages
|
|
154
|
+
|
|
155
|
+
**Usage:**
|
|
156
|
+
- Default initial state
|
|
157
|
+
- Error fallback
|
|
158
|
+
- Empty dataset indication
|
|
159
|
+
|
|
160
|
+
## Cursor-Based Pagination Strategy
|
|
161
|
+
|
|
162
|
+
### Why Cursor-Based?
|
|
163
|
+
|
|
164
|
+
**Benefits:**
|
|
165
|
+
- Scalable (doesn't skip documents)
|
|
166
|
+
- Consistent results (no duplicates)
|
|
167
|
+
- Real-time friendly (new items appear naturally)
|
|
168
|
+
- Better performance (no offset scanning)
|
|
169
|
+
|
|
170
|
+
**Why Not Offset-Based:**
|
|
171
|
+
- Offset scans all skipped documents
|
|
172
|
+
- Slows down with page number
|
|
173
|
+
- Can show duplicates if items added
|
|
174
|
+
- Can miss items if items deleted
|
|
175
|
+
|
|
176
|
+
### Cursor Extraction
|
|
177
|
+
|
|
178
|
+
**Strategy:** Use sortable field value as cursor.
|
|
179
|
+
|
|
180
|
+
**Common Cursor Fields:**
|
|
181
|
+
- `createdAt` timestamp
|
|
182
|
+
- Document ID (`__name__`)
|
|
183
|
+
- Any unique, sortable field
|
|
184
|
+
|
|
185
|
+
**Requirements:**
|
|
186
|
+
- Field must be indexed in Firestore
|
|
187
|
+
- Field must be sortable
|
|
188
|
+
- Consistent across queries
|
|
189
|
+
- Unique per document (preferably)
|
|
190
|
+
|
|
191
|
+
### Page Size Strategy
|
|
192
|
+
|
|
193
|
+
**Recommended Sizes:**
|
|
194
|
+
- Mobile: 10-20 items per page
|
|
195
|
+
- Desktop: 20-50 items per page
|
|
196
|
+
- Infinite scroll: 20 items per page
|
|
197
|
+
|
|
198
|
+
**Considerations:**
|
|
199
|
+
- Larger pages = fewer requests but more data transfer
|
|
200
|
+
- Smaller pages = faster initial load but more requests
|
|
201
|
+
- Consider document size (images, large text)
|
|
202
|
+
- Test with real user data
|
|
203
|
+
|
|
204
|
+
## Common Mistakes to Avoid
|
|
205
|
+
|
|
206
|
+
1. ❌ Using offset-based pagination
|
|
207
|
+
- ✅ Use cursor-based pagination
|
|
208
|
+
|
|
209
|
+
2. ❌ Fetching exactly limit items
|
|
210
|
+
- ✅ Fetch limit + 1 to detect hasMore
|
|
211
|
+
|
|
212
|
+
3. ❌ Not sorting consistently
|
|
213
|
+
- ✅ Always sort same field same direction
|
|
214
|
+
|
|
215
|
+
4. ❌ Complex cursor logic
|
|
216
|
+
- ✅ Use simple field value as cursor
|
|
217
|
+
|
|
218
|
+
5. ❌ Storing entire result in state
|
|
219
|
+
- ✅ Store only cursor, fetch data on demand
|
|
220
|
+
|
|
221
|
+
6. ❌ Not handling last page
|
|
222
|
+
- ✅ Check hasMore before loading more
|
|
223
|
+
|
|
224
|
+
## AI Agent Instructions
|
|
225
|
+
|
|
226
|
+
### When Creating Paginated Repository
|
|
227
|
+
|
|
228
|
+
1. Extend `BasePaginatedRepository<TEntity, TOptions>`
|
|
229
|
+
2. Implement `buildQuery(options, cursor?)` method
|
|
230
|
+
3. Use `PaginationHelper` for result building
|
|
231
|
+
4. Return `PaginatedResult<TEntity>` type
|
|
232
|
+
5. Document cursor field used
|
|
233
|
+
|
|
234
|
+
### When Creating Paginated Hook
|
|
235
|
+
|
|
236
|
+
1. Import types from `src/firestore/types/pagination`
|
|
237
|
+
2. Manage state for data, hasMore, nextCursor
|
|
238
|
+
3. Provide loadMore function
|
|
239
|
+
4. Handle loading and error states
|
|
240
|
+
5. Reset pagination when needed
|
|
241
|
+
|
|
242
|
+
### When Adding Pagination to UI
|
|
243
|
+
|
|
244
|
+
1. Use pagination hook or state
|
|
245
|
+
2. Call loadMore on scroll end
|
|
246
|
+
3. Show loading indicator
|
|
247
|
+
4. Stop when hasMore is false
|
|
248
|
+
5. Handle errors gracefully
|
|
249
|
+
|
|
250
|
+
## Code Quality Standards
|
|
251
|
+
|
|
252
|
+
### TypeScript
|
|
253
|
+
|
|
254
|
+
- Always specify generic type `<T>`
|
|
255
|
+
- Never use `any` type
|
|
256
|
+
- Import types from correct path
|
|
257
|
+
- Use strict type checking
|
|
258
|
+
|
|
259
|
+
### File Organization
|
|
260
|
+
|
|
261
|
+
- One paginated repository per entity
|
|
262
|
+
- Types in separate types file
|
|
263
|
+
- Hooks in presentation layer
|
|
264
|
+
- Tests for pagination logic
|
|
265
|
+
|
|
266
|
+
## Performance Considerations
|
|
267
|
+
|
|
268
|
+
### Fetch Strategy
|
|
269
|
+
|
|
270
|
+
**Always Fetch limit + 1:**
|
|
271
|
+
- Fetch 21 items for pageSize of 20
|
|
272
|
+
- If returned 21, hasMore = true
|
|
273
|
+
- Return only 20 items
|
|
274
|
+
- Use 21st item's cursor for next page
|
|
275
|
+
|
|
276
|
+
**Why +1?**
|
|
277
|
+
- Determines if more pages exist
|
|
278
|
+
- Provides cursor for next page
|
|
279
|
+
- Minimal performance impact
|
|
280
|
+
- Standard pagination pattern
|
|
281
|
+
|
|
282
|
+
### State Management
|
|
283
|
+
|
|
284
|
+
**Store Minimal State:**
|
|
285
|
+
- Cursor string only (not entire result)
|
|
286
|
+
- hasMore boolean
|
|
287
|
+
- Current data array
|
|
288
|
+
- Don't store all pages in state
|
|
289
|
+
|
|
290
|
+
**Why Minimal State?**
|
|
291
|
+
- Reduces memory usage
|
|
292
|
+
- Faster renders
|
|
293
|
+
- Simpler logic
|
|
294
|
+
- Better UX (can refresh)
|
|
295
|
+
|
|
296
|
+
## Related Documentation
|
|
297
|
+
|
|
298
|
+
- [Pagination Helper README](../../utils/pagination.helper/README.md)
|
|
299
|
+
- [Base Paginated Repository README](../../infrastructure/repositories/base-paginated-repository/README.md)
|
|
300
|
+
- [Firestore Module README](../README.md)
|
|
301
|
+
|
|
302
|
+
## API Reference
|
|
303
|
+
|
|
304
|
+
### Main Types
|
|
305
|
+
|
|
306
|
+
**Import Path:** `src/firestore/types/pagination`
|
|
307
|
+
|
|
308
|
+
| Type | Description | Generic |
|
|
309
|
+
|------|-------------|---------|
|
|
310
|
+
| `PaginationParams` | Input parameters for pagination | No |
|
|
311
|
+
| `PaginatedResult<T>` | Result from paginated query | Yes |
|
|
312
|
+
| `EMPTY_PAGINATED_RESULT` | Empty result constant | No |
|
|
313
|
+
|
|
314
|
+
### Type Usage
|
|
315
|
+
|
|
316
|
+
**For Repository Methods:**
|
|
317
|
+
- Return type: `async paginate(params: PaginationParams): Promise<PaginatedResult<User>>`
|
|
318
|
+
- Input type: `params: { pageSize: 20, cursor: 'abc123' }`
|
|
319
|
+
- Specify generic type for type safety
|
|
320
|
+
- TypeScript enforces type consistency
|
|
321
|
+
|
|
322
|
+
**For UI State:**
|
|
323
|
+
- State for data: `useState<User[]>([])`
|
|
324
|
+
- State for hasMore: `useState<boolean>(false)`
|
|
325
|
+
- State for cursor: `useState<string>()`
|
|
326
|
+
- Store cursor for next page requests
|
|
327
|
+
- Check hasMore before loading more
|
|
328
|
+
|
|
329
|
+
---
|
|
330
|
+
|
|
331
|
+
**Last Updated:** 2025-01-08
|
|
332
|
+
**Maintainer:** Firestore Module Team
|