@umituz/react-native-firebase 1.14.4 → 2.0.1
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/package.json +1 -1
- package/src/domains/account-deletion/index.ts +28 -0
- package/src/{auth → domains/account-deletion}/infrastructure/services/account-deletion.service.ts +4 -4
- package/src/{auth → domains/account-deletion}/infrastructure/services/reauthentication.service.ts +5 -5
- package/src/{auth → domains/auth}/index.ts +0 -21
- package/src/{auth → domains/auth}/infrastructure/config/FirebaseAuthClient.ts +2 -2
- package/src/{auth → domains/auth}/infrastructure/services/apple-auth.service.ts +1 -1
- package/src/{auth → domains/auth}/infrastructure/services/auth-listener.service.ts +2 -2
- package/src/{auth → domains/auth}/infrastructure/services/auth-utils.service.ts +1 -1
- package/src/{auth → domains/auth}/infrastructure/services/base/base-auth.service.ts +1 -1
- package/src/{auth → domains/auth}/infrastructure/services/email-auth.service.ts +1 -1
- package/src/{auth → domains/auth}/infrastructure/services/google-auth.service.ts +2 -2
- package/src/{auth → domains/auth}/infrastructure/services/password.service.ts +1 -1
- package/src/{firestore → domains/firestore}/domain/errors/FirebaseFirestoreError.ts +1 -1
- package/src/{firestore → domains/firestore}/infrastructure/config/FirestoreClient.ts +2 -2
- package/src/{firestore → domains/firestore}/infrastructure/services/RequestLoggerService.ts +1 -1
- package/src/{firestore → domains/firestore}/utils/quota-error-detector.util.ts +1 -1
- package/src/{firestore → domains/firestore}/utils/transaction/transaction.util.ts +1 -1
- package/src/index.ts +12 -11
- package/src/init/createFirebaseInitModule.ts +1 -1
- package/src/{domain → shared/domain}/utils/credential.util.ts +1 -1
- package/src/{infrastructure → shared/infrastructure}/config/clients/FirebaseClientSingleton.ts +1 -1
- package/src/auth/domain/errors/README.md +0 -291
- package/src/auth/infrastructure/config/README.md +0 -239
- package/src/auth/infrastructure/services/README.md +0 -346
- package/src/domain/README.md +0 -628
- package/src/firestore/domain/README.md +0 -325
- package/src/firestore/domain/constants/README.md +0 -332
- package/src/firestore/domain/entities/README.md +0 -286
- package/src/firestore/domain/errors/README.md +0 -389
- package/src/firestore/infrastructure/config/README.md +0 -239
- package/src/firestore/infrastructure/middleware/README.md +0 -316
- package/src/firestore/infrastructure/repositories/README.md +0 -425
- package/src/firestore/infrastructure/services/README.md +0 -332
- package/src/firestore/types/pagination/README.md +0 -332
- package/src/firestore/utils/README.md +0 -574
- package/src/firestore/utils/dateUtils/README.md +0 -171
- package/src/firestore/utils/document-mapper.helper/README.md +0 -309
- package/src/firestore/utils/pagination.helper/README.md +0 -298
- package/src/firestore/utils/query-builder/README.md +0 -291
- package/src/infrastructure/README.md +0 -408
- package/src/infrastructure/config/README.md +0 -262
- package/src/presentation/README.md +0 -556
- /package/src/{auth/infrastructure/services → domains/account-deletion/application/ports}/reauthentication.types.ts +0 -0
- /package/src/{auth → domains/auth}/domain/entities/AnonymousUser.ts +0 -0
- /package/src/{auth → domains/auth}/domain/errors/FirebaseAuthError.ts +0 -0
- /package/src/{auth → domains/auth}/domain/value-objects/FirebaseAuthConfig.ts +0 -0
- /package/src/{auth → domains/auth}/infrastructure/config/initializers/FirebaseAuthInitializer.ts +0 -0
- /package/src/{auth → domains/auth}/infrastructure/services/anonymous-auth.service.ts +0 -0
- /package/src/{auth → domains/auth}/infrastructure/services/apple-auth.types.ts +0 -0
- /package/src/{auth → domains/auth}/infrastructure/services/auth-guard.service.ts +0 -0
- /package/src/{auth → domains/auth}/infrastructure/services/crypto.util.ts +0 -0
- /package/src/{auth → domains/auth}/infrastructure/services/firestore-utils.service.ts +0 -0
- /package/src/{auth → domains/auth}/infrastructure/services/google-auth.types.ts +0 -0
- /package/src/{auth → domains/auth}/infrastructure/services/google-oauth.service.ts +0 -0
- /package/src/{auth → domains/auth}/infrastructure/services/user-document-builder.util.ts +0 -0
- /package/src/{auth → domains/auth}/infrastructure/services/user-document.service.ts +0 -0
- /package/src/{auth → domains/auth}/infrastructure/services/user-document.types.ts +0 -0
- /package/src/{auth → domains/auth}/infrastructure/stores/auth.store.ts +0 -0
- /package/src/{auth → domains/auth}/presentation/hooks/shared/auth-hooks.util.ts +0 -0
- /package/src/{auth → domains/auth}/presentation/hooks/shared/hook-utils.util.ts +0 -0
- /package/src/{auth → domains/auth}/presentation/hooks/shared/safe-state-hooks.util.ts +0 -0
- /package/src/{auth → domains/auth}/presentation/hooks/shared/state-hooks.util.ts +0 -0
- /package/src/{auth → domains/auth}/presentation/hooks/useAnonymousAuth.ts +0 -0
- /package/src/{auth → domains/auth}/presentation/hooks/useFirebaseAuth.ts +0 -0
- /package/src/{auth → domains/auth}/presentation/hooks/useGoogleOAuth.ts +0 -0
- /package/src/{auth → domains/auth}/presentation/hooks/useSocialAuth.ts +0 -0
- /package/src/{auth → domains/auth}/presentation/hooks/utils/auth-state-change.handler.ts +0 -0
- /package/src/{firestore → domains/firestore}/domain/constants/QuotaLimits.ts +0 -0
- /package/src/{firestore → domains/firestore}/domain/entities/QuotaMetrics.ts +0 -0
- /package/src/{firestore → domains/firestore}/domain/entities/RequestLog.ts +0 -0
- /package/src/{firestore → domains/firestore}/domain/services/QuotaCalculator.ts +0 -0
- /package/src/{firestore → domains/firestore}/index.ts +0 -0
- /package/src/{firestore → domains/firestore}/infrastructure/config/initializers/FirebaseFirestoreInitializer.ts +0 -0
- /package/src/{firestore → domains/firestore}/infrastructure/middleware/QueryDeduplicationMiddleware.ts +0 -0
- /package/src/{firestore → domains/firestore}/infrastructure/middleware/QuotaTrackingMiddleware.ts +0 -0
- /package/src/{firestore → domains/firestore}/infrastructure/repositories/BasePaginatedRepository.ts +0 -0
- /package/src/{firestore → domains/firestore}/infrastructure/repositories/BaseQueryRepository.ts +0 -0
- /package/src/{firestore → domains/firestore}/infrastructure/repositories/BaseRepository.ts +0 -0
- /package/src/{firestore → domains/firestore}/types/pagination.types.ts +0 -0
- /package/src/{firestore → domains/firestore}/utils/dateUtils.ts +0 -0
- /package/src/{firestore → domains/firestore}/utils/deduplication/pending-query-manager.util.ts +0 -0
- /package/src/{firestore → domains/firestore}/utils/deduplication/query-key-generator.util.ts +0 -0
- /package/src/{firestore → domains/firestore}/utils/deduplication/timer-manager.util.ts +0 -0
- /package/src/{firestore → domains/firestore}/utils/document-mapper.helper.ts +0 -0
- /package/src/{firestore → domains/firestore}/utils/firestore-helper.ts +0 -0
- /package/src/{firestore → domains/firestore}/utils/mapper/base-mapper.util.ts +0 -0
- /package/src/{firestore → domains/firestore}/utils/mapper/enrichment-mapper.util.ts +0 -0
- /package/src/{firestore → domains/firestore}/utils/mapper/multi-enrichment-mapper.util.ts +0 -0
- /package/src/{firestore → domains/firestore}/utils/operation/operation-executor.util.ts +0 -0
- /package/src/{firestore → domains/firestore}/utils/pagination.helper.ts +0 -0
- /package/src/{firestore → domains/firestore}/utils/query/filters.util.ts +0 -0
- /package/src/{firestore → domains/firestore}/utils/query/modifiers.util.ts +0 -0
- /package/src/{firestore → domains/firestore}/utils/query-builder.ts +0 -0
- /package/src/{firestore → domains/firestore}/utils/result/result.util.ts +0 -0
- /package/src/{domain → shared/domain}/errors/FirebaseError.ts +0 -0
- /package/src/{domain → shared/domain}/guards/firebase-error.guard.ts +0 -0
- /package/src/{domain → shared/domain}/utils/async-executor.util.ts +0 -0
- /package/src/{domain → shared/domain}/utils/error-handler.util.ts +0 -0
- /package/src/{domain → shared/domain}/utils/error-handlers/error-checkers.ts +0 -0
- /package/src/{domain → shared/domain}/utils/error-handlers/error-converters.ts +0 -0
- /package/src/{domain → shared/domain}/utils/error-handlers/error-messages.ts +0 -0
- /package/src/{domain → shared/domain}/utils/executors/advanced-executors.util.ts +0 -0
- /package/src/{domain → shared/domain}/utils/executors/basic-executors.util.ts +0 -0
- /package/src/{domain → shared/domain}/utils/executors/batch-executors.util.ts +0 -0
- /package/src/{domain → shared/domain}/utils/executors/error-converters.util.ts +0 -0
- /package/src/{domain → shared/domain}/utils/id-generator.util.ts +0 -0
- /package/src/{domain → shared/domain}/utils/index.ts +0 -0
- /package/src/{domain → shared/domain}/utils/result/result-creators.ts +0 -0
- /package/src/{domain → shared/domain}/utils/result/result-helpers.ts +0 -0
- /package/src/{domain → shared/domain}/utils/result/result-types.ts +0 -0
- /package/src/{domain → shared/domain}/utils/result.util.ts +0 -0
- /package/src/{domain → shared/domain}/utils/service-config.util.ts +0 -0
- /package/src/{domain → shared/domain}/utils/type-guards.util.ts +0 -0
- /package/src/{domain → shared/domain}/utils/validation.util.ts +0 -0
- /package/src/{domain → shared/domain}/utils/validators/composite.validator.ts +0 -0
- /package/src/{domain → shared/domain}/utils/validators/firebase.validator.ts +0 -0
- /package/src/{domain → shared/domain}/utils/validators/generic.validator.ts +0 -0
- /package/src/{domain → shared/domain}/utils/validators/string.validator.ts +0 -0
- /package/src/{domain → shared/domain}/utils/validators/url.validator.ts +0 -0
- /package/src/{domain → shared/domain}/utils/validators/user-input.validator.ts +0 -0
- /package/src/{domain → shared/domain}/value-objects/FirebaseConfig.ts +0 -0
- /package/src/{infrastructure → shared/infrastructure}/config/FirebaseClient.ts +0 -0
- /package/src/{infrastructure → shared/infrastructure}/config/FirebaseConfigLoader.ts +0 -0
- /package/src/{infrastructure → shared/infrastructure}/config/base/ClientStateManager.ts +0 -0
- /package/src/{infrastructure → shared/infrastructure}/config/base/ServiceClientSingleton.ts +0 -0
- /package/src/{infrastructure → shared/infrastructure}/config/initializers/FirebaseAppInitializer.ts +0 -0
- /package/src/{infrastructure → shared/infrastructure}/config/orchestrators/FirebaseInitializationOrchestrator.ts +0 -0
- /package/src/{infrastructure → shared/infrastructure}/config/services/FirebaseInitializationService.ts +0 -0
- /package/src/{infrastructure → shared/infrastructure}/config/services/FirebaseServiceInitializer.ts +0 -0
- /package/src/{infrastructure → shared/infrastructure}/config/state/FirebaseClientState.ts +0 -0
- /package/src/{infrastructure → shared/infrastructure}/config/validators/FirebaseConfigValidator.ts +0 -0
|
@@ -1,298 +0,0 @@
|
|
|
1
|
-
# Pagination Helper
|
|
2
|
-
|
|
3
|
-
Cursor-based pagination utilities for Firestore queries with type-safe result handling.
|
|
4
|
-
|
|
5
|
-
## Purpose
|
|
6
|
-
|
|
7
|
-
Provides consistent pagination logic across all Firestore queries using cursor-based pagination (not offset-based). Handles hasMore detection and cursor extraction for any document type.
|
|
8
|
-
|
|
9
|
-
## For AI Agents
|
|
10
|
-
|
|
11
|
-
### Before Using Pagination Helper
|
|
12
|
-
|
|
13
|
-
1. **UNDERSTAND** cursor-based vs offset-based pagination
|
|
14
|
-
2. **ALWAYS** fetch limit + 1 documents for hasMore detection
|
|
15
|
-
3. **USE** generic type parameter for type safety
|
|
16
|
-
4. **EXTRACT** cursor from appropriate field
|
|
17
|
-
|
|
18
|
-
### Required Practices
|
|
19
|
-
|
|
20
|
-
1. **Fetch limit + 1** documents to detect if more pages exist
|
|
21
|
-
2. **Use cursor from last visible document** for next page
|
|
22
|
-
3. **Sort consistently** for stable pagination
|
|
23
|
-
4. **Handle edge cases** (empty results, last page)
|
|
24
|
-
5. **Use generic type parameter** for type safety
|
|
25
|
-
|
|
26
|
-
### Forbidden Practices
|
|
27
|
-
|
|
28
|
-
## ❌ NEVER
|
|
29
|
-
|
|
30
|
-
- Use offset-based pagination (skip/take) - not scalable
|
|
31
|
-
- Fetch exactly limit documents (can't detect hasMore)
|
|
32
|
-
- Use document ID as cursor unless sorted by ID
|
|
33
|
-
- Assume pagination state in frontend (always from backend)
|
|
34
|
-
- Paginate without sorting
|
|
35
|
-
|
|
36
|
-
## ⚠️ Avoid
|
|
37
|
-
|
|
38
|
-
- Large page sizes (use 10-50)
|
|
39
|
-
- Inconsistent sort orders between pages
|
|
40
|
-
- Complex cursor extraction logic
|
|
41
|
-
- Not handling last page correctly
|
|
42
|
-
|
|
43
|
-
## Usage Strategies
|
|
44
|
-
|
|
45
|
-
### For Cursor-Based Pagination
|
|
46
|
-
|
|
47
|
-
**Strategy:** Use last document's field as cursor for next page.
|
|
48
|
-
|
|
49
|
-
**When to Use:**
|
|
50
|
-
- Infinite scroll implementations
|
|
51
|
-
- Large dataset navigation
|
|
52
|
-
- Ordered result sets
|
|
53
|
-
- Real-time data streams
|
|
54
|
-
|
|
55
|
-
**Why Cursor-Based:**
|
|
56
|
-
- Scalable (doesn't skip documents)
|
|
57
|
-
- Consistent results (no missing/duplicate items)
|
|
58
|
-
- Performance (doesn't scan skipped documents)
|
|
59
|
-
- Real-time friendly (new items appear naturally)
|
|
60
|
-
|
|
61
|
-
**Approach:**
|
|
62
|
-
1. Fetch limit + 1 documents
|
|
63
|
-
2. If returned > limit, hasMore = true
|
|
64
|
-
3. Use last item's cursor for next page
|
|
65
|
-
4. Store cursor in frontend state
|
|
66
|
-
|
|
67
|
-
### For Different Cursor Types
|
|
68
|
-
|
|
69
|
-
**By Timestamp:**
|
|
70
|
-
- Use creation time field
|
|
71
|
-
- Requires sorting by timestamp
|
|
72
|
-
- Most common for chronological feeds
|
|
73
|
-
|
|
74
|
-
**By ID:**
|
|
75
|
-
- Use document ID
|
|
76
|
-
- Requires sorting by __name__
|
|
77
|
-
- Good for lexicographic ordering
|
|
78
|
-
|
|
79
|
-
**By Custom Field:**
|
|
80
|
-
- Use any sortable field
|
|
81
|
-
- Requires consistent sorting
|
|
82
|
-
- Must be unique and stable
|
|
83
|
-
|
|
84
|
-
### For Type Safety
|
|
85
|
-
|
|
86
|
-
**Strategy:** Use generic type parameter <T>.
|
|
87
|
-
|
|
88
|
-
**When to Use:**
|
|
89
|
-
- Strongly typed document entities
|
|
90
|
-
- Type-safe cursor extraction
|
|
91
|
-
- Compile-time type checking
|
|
92
|
-
|
|
93
|
-
**Approach:**
|
|
94
|
-
1. Define document type
|
|
95
|
-
2. Create helper with type parameter
|
|
96
|
-
3. Type-safe access to fields
|
|
97
|
-
4. Type-safe cursor extraction
|
|
98
|
-
|
|
99
|
-
## API Reference
|
|
100
|
-
|
|
101
|
-
### PaginationHelper<T>
|
|
102
|
-
|
|
103
|
-
Generic helper class for pagination logic.
|
|
104
|
-
|
|
105
|
-
Constructor: No parameters required
|
|
106
|
-
|
|
107
|
-
Methods:
|
|
108
|
-
|
|
109
|
-
#### `buildResult(items: T[], pageLimit: number, getCursor: (item: T) => string)`
|
|
110
|
-
|
|
111
|
-
Build paginated result from fetched items.
|
|
112
|
-
|
|
113
|
-
**Parameters:**
|
|
114
|
-
- **items**: All fetched items (should be limit + 1)
|
|
115
|
-
- **pageLimit**: Requested page size
|
|
116
|
-
- **getCursor**: Function to extract cursor from item
|
|
117
|
-
|
|
118
|
-
**Returns:** PaginatedResult<T>
|
|
119
|
-
|
|
120
|
-
**Behavior:**
|
|
121
|
-
- If items.length > limit: hasMore = true, trims to limit
|
|
122
|
-
- If items.length <= limit: hasMore = false, returns all items
|
|
123
|
-
- Extracts cursor from last item for next page
|
|
124
|
-
|
|
125
|
-
#### `getLimit(params?: PaginationParams, defaultLimit?: number)`
|
|
126
|
-
|
|
127
|
-
Extract limit from pagination params or use default.
|
|
128
|
-
|
|
129
|
-
**Parameters:**
|
|
130
|
-
- **params**: Optional pagination parameters
|
|
131
|
-
- **defaultLimit**: Default limit (default: 10)
|
|
132
|
-
|
|
133
|
-
**Returns:** number - Page limit to use
|
|
134
|
-
|
|
135
|
-
#### `getFetchLimit(pageLimit: number)`
|
|
136
|
-
|
|
137
|
-
Calculate fetch limit (page limit + 1 for hasMore detection).
|
|
138
|
-
|
|
139
|
-
**Parameters:**
|
|
140
|
-
- **pageLimit**: Requested page size
|
|
141
|
-
|
|
142
|
-
**Returns:** number - Fetch limit (pageLimit + 1)
|
|
143
|
-
|
|
144
|
-
**Why:** Fetch one extra to detect if more pages exist.
|
|
145
|
-
|
|
146
|
-
#### `hasCursor(params?: PaginationParams)`
|
|
147
|
-
|
|
148
|
-
Check if pagination params has a cursor.
|
|
149
|
-
|
|
150
|
-
**Parameters:**
|
|
151
|
-
- **params**: Optional pagination parameters
|
|
152
|
-
|
|
153
|
-
**Returns:** boolean - True if cursor exists
|
|
154
|
-
|
|
155
|
-
**Use For:** Determining if this is a first page or subsequent page
|
|
156
|
-
|
|
157
|
-
### Helper Functions
|
|
158
|
-
|
|
159
|
-
#### `createPaginationHelper<T>()`
|
|
160
|
-
|
|
161
|
-
Factory function to create typed pagination helper.
|
|
162
|
-
|
|
163
|
-
**Returns:** PaginationHelper<T>
|
|
164
|
-
|
|
165
|
-
**Use For:** Cleaner API, type inference
|
|
166
|
-
|
|
167
|
-
## Result Types
|
|
168
|
-
|
|
169
|
-
### PaginatedResult<T>
|
|
170
|
-
|
|
171
|
-
- **items**: T[] - Paginated items (trimmed to limit)
|
|
172
|
-
- **nextCursor**: string | null - Cursor for next page (null if no more)
|
|
173
|
-
- **hasMore**: boolean - Whether more pages exist
|
|
174
|
-
|
|
175
|
-
### PaginationParams
|
|
176
|
-
|
|
177
|
-
- **cursor**: string | null - Current page cursor
|
|
178
|
-
- **limit**: number | null - Page size limit
|
|
179
|
-
|
|
180
|
-
## Common Mistakes to Avoid
|
|
181
|
-
|
|
182
|
-
1. ❌ Fetching exactly limit documents
|
|
183
|
-
- ✅ Fetch limit + 1 to detect hasMore
|
|
184
|
-
|
|
185
|
-
2. ❌ Using offset-based pagination
|
|
186
|
-
- ✅ Use cursor-based pagination
|
|
187
|
-
|
|
188
|
-
3. ❌ Not sorting consistently
|
|
189
|
-
- ✅ Always sort same field in same direction
|
|
190
|
-
|
|
191
|
-
4. ❌ Complex cursor logic
|
|
192
|
-
- ✅ Use simple field-based cursor extraction
|
|
193
|
-
|
|
194
|
-
5. ❌ Not handling last page
|
|
195
|
-
- ✅ Return hasMore: false when items <= limit
|
|
196
|
-
|
|
197
|
-
## AI Agent Instructions
|
|
198
|
-
|
|
199
|
-
### When Implementing Pagination
|
|
200
|
-
|
|
201
|
-
1. Always fetch limit + 1 documents
|
|
202
|
-
2. Use buildResult to handle hasMore logic
|
|
203
|
-
3. Extract cursor from sorted field
|
|
204
|
-
4. Store nextCursor for subsequent requests
|
|
205
|
-
5. Handle null cursor (first page)
|
|
206
|
-
|
|
207
|
-
### When Creating Paginated Repository
|
|
208
|
-
|
|
209
|
-
1. Extend BasePaginatedRepository
|
|
210
|
-
2. Use PaginationHelper in implementation
|
|
211
|
-
3. Accept PaginationParams in query methods
|
|
212
|
-
4. Return PaginatedResult type
|
|
213
|
-
5. Document cursor field used
|
|
214
|
-
|
|
215
|
-
### For Custom Cursor Logic
|
|
216
|
-
|
|
217
|
-
1. Keep getCursor function simple
|
|
218
|
-
2. Extract from sorted field
|
|
219
|
-
3. Return string representation
|
|
220
|
-
4. Handle null/undefined gracefully
|
|
221
|
-
5. Document cursor extraction logic
|
|
222
|
-
|
|
223
|
-
## Integration with Repositories
|
|
224
|
-
|
|
225
|
-
**Strategy:** Use PaginationHelper in BasePaginatedRepository.
|
|
226
|
-
|
|
227
|
-
**Repository Implementation:**
|
|
228
|
-
1. Extract limit from params using getLimit()
|
|
229
|
-
2. Calculate fetch limit using getFetchLimit()
|
|
230
|
-
3. Build query with cursor if hasCursor() is true
|
|
231
|
-
4. Fetch fetchLimit documents
|
|
232
|
-
5. Build result using buildResult()
|
|
233
|
-
|
|
234
|
-
## Performance Considerations
|
|
235
|
-
|
|
236
|
-
### Page Size Guidelines
|
|
237
|
-
|
|
238
|
-
- **Small pages (10-20)**: Better for mobile, less data transfer
|
|
239
|
-
- **Medium pages (20-50)**: Good balance
|
|
240
|
-
- **Large pages (50-100)**: Fewer requests, more data
|
|
241
|
-
|
|
242
|
-
**Recommendation:** Start with 20, adjust based on:
|
|
243
|
-
|
|
244
|
-
- Document size
|
|
245
|
-
- Network conditions
|
|
246
|
-
- UI requirements
|
|
247
|
-
- User behavior
|
|
248
|
-
|
|
249
|
-
### Query Performance
|
|
250
|
-
|
|
251
|
-
- Cursor-based queries are efficient
|
|
252
|
-
- No document scanning for offsets
|
|
253
|
-
- Index usage for sorting
|
|
254
|
-
- Consistent performance regardless of page number
|
|
255
|
-
|
|
256
|
-
## Code Quality Standards
|
|
257
|
-
|
|
258
|
-
### TypeScript
|
|
259
|
-
|
|
260
|
-
- Always use generic type parameter <T>
|
|
261
|
-
- Define proper return types
|
|
262
|
-
- Export pagination types
|
|
263
|
-
- Use strict type checking
|
|
264
|
-
|
|
265
|
-
### Error Handling
|
|
266
|
-
|
|
267
|
-
- Handle empty item arrays
|
|
268
|
-
- Handle null cursor
|
|
269
|
-
- Validate page limit > 0
|
|
270
|
-
- Handle invalid cursor values
|
|
271
|
-
|
|
272
|
-
## Related Documentation
|
|
273
|
-
|
|
274
|
-
- [Pagination Types README](../../types/pagination/README.md)
|
|
275
|
-
- [Base Paginated Repository README](../../infrastructure/repositories/base-paginated-repository/README.md)
|
|
276
|
-
- [Query Builder README](../query-builder/README.md)
|
|
277
|
-
|
|
278
|
-
## Migration Guide
|
|
279
|
-
|
|
280
|
-
### From Offset-Based Pagination
|
|
281
|
-
|
|
282
|
-
**Don't Do (Offset-Based - Not Scalable):**
|
|
283
|
-
- Parameter: `skip: (page - 1) * limit`
|
|
284
|
-
- Parameter: `limit: limit`
|
|
285
|
-
- Problem: Scans all skipped documents
|
|
286
|
-
- Problem: Doesn't scale (slows with page number)
|
|
287
|
-
|
|
288
|
-
**Do Instead (Cursor-Based - Scalable):**
|
|
289
|
-
- Parameter: `cursor: lastDocumentCursor`
|
|
290
|
-
- Parameter: `limit: limit`
|
|
291
|
-
- Benefit: Starts from specific position
|
|
292
|
-
- Benefit: Performs consistently
|
|
293
|
-
- Benefit: Scales to large datasets
|
|
294
|
-
|
|
295
|
-
---
|
|
296
|
-
|
|
297
|
-
**Last Updated:** 2025-01-08
|
|
298
|
-
**Maintainer:** Firestore Module Team
|
|
@@ -1,291 +0,0 @@
|
|
|
1
|
-
# Query Builder
|
|
2
|
-
|
|
3
|
-
Advanced Firestore query building utility with support for filtering, sorting, pagination, and date ranges.
|
|
4
|
-
|
|
5
|
-
## Purpose
|
|
6
|
-
|
|
7
|
-
Provides a fluent interface for building complex Firestore queries while handling Firestore limitations (e.g., IN operator 10-item limit).
|
|
8
|
-
|
|
9
|
-
## For AI Agents
|
|
10
|
-
|
|
11
|
-
### Before Using Query Builder
|
|
12
|
-
|
|
13
|
-
1. **UNDERSTAND** Firestore query limitations
|
|
14
|
-
2. **USE** builder instead of raw Firestore queries
|
|
15
|
-
3. **RESPECT** compound query limitations
|
|
16
|
-
4. **HANDLE** large arrays with chunking
|
|
17
|
-
|
|
18
|
-
### Required Practices
|
|
19
|
-
|
|
20
|
-
1. **Use query builder** for complex queries
|
|
21
|
-
2. **Handle IN operator limits** (max 10 values)
|
|
22
|
-
3. **Apply modifiers in correct order** (filters → date range → sort → cursor → limit)
|
|
23
|
-
4. **Use pagination** for large datasets
|
|
24
|
-
|
|
25
|
-
### Forbidden Practices
|
|
26
|
-
|
|
27
|
-
## ❌ NEVER
|
|
28
|
-
|
|
29
|
-
- Build queries manually with Firestore SDK
|
|
30
|
-
- Use IN operator with more than 10 values without chunking
|
|
31
|
-
- Apply modifiers in wrong order
|
|
32
|
-
- Create compound queries that violate Firestore rules
|
|
33
|
-
- Ignore pagination for large result sets
|
|
34
|
-
|
|
35
|
-
## ⚠️ Avoid
|
|
36
|
-
|
|
37
|
-
- Multiple range filters on different fields
|
|
38
|
-
- Sorting + filtering on different fields without composite index
|
|
39
|
-
- Very large IN arrays (use pagination instead)
|
|
40
|
-
- Complex OR queries (performance impact)
|
|
41
|
-
|
|
42
|
-
## Usage Strategies
|
|
43
|
-
|
|
44
|
-
### For Complex Filtering
|
|
45
|
-
|
|
46
|
-
**Strategy:** Use FieldFilter array for multiple conditions.
|
|
47
|
-
|
|
48
|
-
**When to Use:**
|
|
49
|
-
- Filtering by multiple fields
|
|
50
|
-
- Combining equality and range filters
|
|
51
|
-
- Building dynamic queries based on user input
|
|
52
|
-
|
|
53
|
-
**Approach:**
|
|
54
|
-
1. Create FieldFilter objects for each condition
|
|
55
|
-
2. Add to baseFilters array
|
|
56
|
-
3. Pass to buildQuery with other options
|
|
57
|
-
|
|
58
|
-
### For Date Range Queries
|
|
59
|
-
|
|
60
|
-
**Strategy:** Use dateRange option for time-based filtering.
|
|
61
|
-
|
|
62
|
-
**When to Use:**
|
|
63
|
-
- Filtering by creation/update time
|
|
64
|
-
- Date-based analytics queries
|
|
65
|
-
- Time-series data retrieval
|
|
66
|
-
|
|
67
|
-
**Approach:**
|
|
68
|
-
1. Specify field name (e.g., 'createdAt')
|
|
69
|
-
2. Provide startDate and/or endDate as timestamps
|
|
70
|
-
3. Combine with sorting on same field
|
|
71
|
-
|
|
72
|
-
### For Pagination
|
|
73
|
-
|
|
74
|
-
**Strategy:** Use cursorValue with limit for cursor-based pagination.
|
|
75
|
-
|
|
76
|
-
**When to Use:**
|
|
77
|
-
- Infinite scroll implementations
|
|
78
|
-
- Large dataset navigation
|
|
79
|
-
- Ordered result sets
|
|
80
|
-
|
|
81
|
-
**Approach:**
|
|
82
|
-
1. Store cursor from last page
|
|
83
|
-
2. Pass as cursorValue in next request
|
|
84
|
-
3. Always use with sort and limit
|
|
85
|
-
|
|
86
|
-
### For Large IN Arrays
|
|
87
|
-
|
|
88
|
-
**Strategy:** Let builder handle chunking automatically.
|
|
89
|
-
|
|
90
|
-
**When to Use:**
|
|
91
|
-
- Filtering by list of IDs
|
|
92
|
-
- Multiple category selection
|
|
93
|
-
- Tag-based filtering
|
|
94
|
-
|
|
95
|
-
**Approach:**
|
|
96
|
-
1. Create filter with operator: 'in'
|
|
97
|
-
2. Pass array (any size supported)
|
|
98
|
-
3. Builder splits into chunks of 10 automatically
|
|
99
|
-
|
|
100
|
-
## Configuration Options
|
|
101
|
-
|
|
102
|
-
### QueryBuilderOptions
|
|
103
|
-
|
|
104
|
-
**collectionName** (required)
|
|
105
|
-
- Target collection path
|
|
106
|
-
- Type: string
|
|
107
|
-
|
|
108
|
-
**baseFilters** (optional)
|
|
109
|
-
- Array of field filters
|
|
110
|
-
- Type: FieldFilter[]
|
|
111
|
-
- Applied first in query chain
|
|
112
|
-
|
|
113
|
-
**dateRange** (optional)
|
|
114
|
-
- Date range filter
|
|
115
|
-
- Type: { field: string; startDate?: number; endDate?: number }
|
|
116
|
-
- Use Timestamps for dates
|
|
117
|
-
|
|
118
|
-
**sort** (optional)
|
|
119
|
-
- Sort configuration
|
|
120
|
-
- Type: { field: string; order?: 'asc' | 'desc' }
|
|
121
|
-
- Defaults to 'desc' if not specified
|
|
122
|
-
|
|
123
|
-
**limitValue** (optional)
|
|
124
|
-
- Maximum documents to return
|
|
125
|
-
- Type: number
|
|
126
|
-
- Use for pagination and performance
|
|
127
|
-
|
|
128
|
-
**cursorValue** (optional)
|
|
129
|
-
- Pagination cursor (timestamp)
|
|
130
|
-
- Type: number
|
|
131
|
-
- Requires sort to be set
|
|
132
|
-
|
|
133
|
-
### FieldFilter
|
|
134
|
-
|
|
135
|
-
**field** (required)
|
|
136
|
-
- Document field to filter on
|
|
137
|
-
- Type: string
|
|
138
|
-
|
|
139
|
-
**operator** (required)
|
|
140
|
-
- Comparison operator
|
|
141
|
-
- Type: WhereFilterOp (==, !=, >, >=, <, <=, in, array-contains)
|
|
142
|
-
|
|
143
|
-
**value** (required)
|
|
144
|
-
- Filter value
|
|
145
|
-
- Type: string | number | boolean | string[] | number[]
|
|
146
|
-
|
|
147
|
-
## Helper Functions
|
|
148
|
-
|
|
149
|
-
**Import from:** `src/firestore/utils/query-builder`
|
|
150
|
-
|
|
151
|
-
### `createInFilter(field, values)`
|
|
152
|
-
|
|
153
|
-
Create filter for IN operator.
|
|
154
|
-
|
|
155
|
-
**Use For:**
|
|
156
|
-
- Filtering by multiple values
|
|
157
|
-
- ID list queries
|
|
158
|
-
- Category/tag filtering
|
|
159
|
-
|
|
160
|
-
**Note:** Automatically chunks arrays larger than 10 values.
|
|
161
|
-
|
|
162
|
-
### `createEqualFilter(field, value)`
|
|
163
|
-
|
|
164
|
-
Create filter for equality comparison.
|
|
165
|
-
|
|
166
|
-
**Use For:**
|
|
167
|
-
- Single value matches
|
|
168
|
-
- ID lookups
|
|
169
|
-
- Status filtering
|
|
170
|
-
|
|
171
|
-
## Query Building Order
|
|
172
|
-
|
|
173
|
-
**REQUIRED ORDER:** Modifiers must be applied in this sequence:
|
|
174
|
-
|
|
175
|
-
1. **Collection reference** (base)
|
|
176
|
-
2. **Base filters** (where clauses)
|
|
177
|
-
3. **Date range** (>= and <=)
|
|
178
|
-
4. **Sort** (orderBy)
|
|
179
|
-
5. **Cursor** (startAfter)
|
|
180
|
-
6. **Limit** (limit)
|
|
181
|
-
|
|
182
|
-
**Why this order?**
|
|
183
|
-
- Firestore requires specific order for composite queries
|
|
184
|
-
- Filters before sorts
|
|
185
|
-
- Sorts before cursors
|
|
186
|
-
- Cursors before limits
|
|
187
|
-
|
|
188
|
-
## Common Mistakes to Avoid
|
|
189
|
-
|
|
190
|
-
1. ❌ Manual query construction
|
|
191
|
-
- ✅ Use buildQuery utility
|
|
192
|
-
|
|
193
|
-
2. ❌ IN operator with 11+ values without chunking
|
|
194
|
-
- ✅ Builder handles this automatically
|
|
195
|
-
|
|
196
|
-
3. ❌ Wrong modifier order
|
|
197
|
-
- ✅ Follow prescribed order in buildQuery
|
|
198
|
-
|
|
199
|
-
4. ❌ Pagination without sort
|
|
200
|
-
- ✅ Always include sort when using cursor
|
|
201
|
-
|
|
202
|
-
5. ❌ Multiple range filters on different fields
|
|
203
|
-
- ✅ Use single range filter or create composite index
|
|
204
|
-
|
|
205
|
-
## AI Agent Instructions
|
|
206
|
-
|
|
207
|
-
### When Adding Query Features
|
|
208
|
-
|
|
209
|
-
1. Check Firestore limitations first
|
|
210
|
-
2. Handle edge cases (null, undefined, empty arrays)
|
|
211
|
-
3. Document query capabilities
|
|
212
|
-
4. Update this README
|
|
213
|
-
|
|
214
|
-
### When Building Queries
|
|
215
|
-
|
|
216
|
-
1. Use buildQuery, not raw Firestore SDK
|
|
217
|
-
2. Handle IN operator limits (10 items max per clause)
|
|
218
|
-
3. Respect composite query requirements
|
|
219
|
-
4. Always paginate large result sets
|
|
220
|
-
5. Create composite indexes in Firebase Console when needed
|
|
221
|
-
|
|
222
|
-
### For Complex Queries
|
|
223
|
-
|
|
224
|
-
1. Break into multiple queries if needed
|
|
225
|
-
2. Consider client-side filtering for complex logic
|
|
226
|
-
3. Use denormalization for better query patterns
|
|
227
|
-
4. Document query requirements
|
|
228
|
-
|
|
229
|
-
## Code Quality Standards
|
|
230
|
-
|
|
231
|
-
### TypeScript
|
|
232
|
-
|
|
233
|
-
- All options must have explicit types
|
|
234
|
-
- Export types for consumer use
|
|
235
|
-
- Use strict type checking
|
|
236
|
-
- Document generic type parameters
|
|
237
|
-
|
|
238
|
-
### Error Handling
|
|
239
|
-
|
|
240
|
-
- Validate required options
|
|
241
|
-
- Provide clear error messages
|
|
242
|
-
- Handle Firestore limitations gracefully
|
|
243
|
-
- Log warnings for anti-patterns
|
|
244
|
-
|
|
245
|
-
## Performance Considerations
|
|
246
|
-
|
|
247
|
-
### Query Optimization
|
|
248
|
-
|
|
249
|
-
1. **Limit results** always use limitValue
|
|
250
|
-
2. **Create indexes** for composite queries
|
|
251
|
-
3. **Avoid large offsets** use cursor-based pagination
|
|
252
|
-
4. **Select specific fields** when possible (future feature)
|
|
253
|
-
|
|
254
|
-
### Quota Management
|
|
255
|
-
|
|
256
|
-
1. Each query reads all matched documents
|
|
257
|
-
2. Use limit to control reads
|
|
258
|
-
3. Date range filters reduce scanned documents
|
|
259
|
-
4. Monitor query performance in Firebase Console
|
|
260
|
-
|
|
261
|
-
## Related Documentation
|
|
262
|
-
|
|
263
|
-
- [Firestore Module README](../README.md)
|
|
264
|
-
- [Repository README](../../infrastructure/repositories/README.md)
|
|
265
|
-
- [Pagination Helper README](../pagination.helper/README.md)
|
|
266
|
-
- [Date Utilities README](../dateUtils/README.md)
|
|
267
|
-
|
|
268
|
-
## Firebase Query Limitations
|
|
269
|
-
|
|
270
|
-
### Composite Queries
|
|
271
|
-
|
|
272
|
-
- Maximum 1 range filter (<, <=, >, >=)
|
|
273
|
-
- Range filter and sort must be on same field
|
|
274
|
-
- Requires composite index for most combinations
|
|
275
|
-
|
|
276
|
-
### IN Operator
|
|
277
|
-
|
|
278
|
-
- Maximum 10 values per query
|
|
279
|
-
- Builder auto-chunks larger arrays
|
|
280
|
-
- Each chunk counts as separate query for quota
|
|
281
|
-
|
|
282
|
-
### OR Queries
|
|
283
|
-
|
|
284
|
-
- Maximum 30 disjunctions
|
|
285
|
-
- Can impact performance
|
|
286
|
-
- Use sparingly
|
|
287
|
-
|
|
288
|
-
---
|
|
289
|
-
|
|
290
|
-
**Last Updated:** 2025-01-08
|
|
291
|
-
**Maintainer:** Firestore Module Team
|