-
Notifications
You must be signed in to change notification settings - Fork 2
/
queryCollectionItems.ts
112 lines (108 loc) · 3.41 KB
/
queryCollectionItems.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import { firestore } from 'firebase-admin'
import { createFirestoreDataConverter } from './createFirestoreDataConverter'
/**
* Represents a condition for querying Firestore collections.
*/
type QueryCondition = {
field?: string
operator?: firestore.WhereFilterOp
value?: any
orderDirection?: firestore.OrderByDirection // "asc" or "desc"
limit?: number
}
/**
* Queries the specified collection in Firestore based on the provided conditions
* and returns an array of documents that match the conditions.
*
* @param db - The instance of the Firestore database to use.
* @param collectionPath - The path of the collection to be queried.
* @param conditions - An array of conditions to apply to the query.
*
* @returns An array of documents from the collection that match the conditions.
*
* @throws Throws an exception with an error message if an error occurs.
*
* @example
* ```typescript
* import { firestore } from 'firebase-admin'
* import { query } from '@skeet-framework/firestore'
* const db = firestore();
*
* // Simple query to get users over 25 years old
* const simpleConditions: QueryCondition[] = [
* { field: "age", operator: ">", value: 25 }
* ];
*
* // Advanced query to get users over 25 years old, ordered by their names
* const advancedConditions: QueryCondition[] = [
* { field: "age", operator: ">", value: 25 },
* { field: "name", orderDirection: "asc" }
* ];
*
* // Query to get users over 25 years old and limit the results to 5
* const limitedConditions: QueryCondition[] = [
* { field: "age", operator: ">", value: 25 },
* { limit: 5 }
* ];
*
* async function run() {
* try {
* const path = 'Users';
*
* // Using the simple conditions
* const usersByAge = await query<User>(db, path, simpleConditions);
* console.log(`Found ${usersByAge.length} users over 25 years old.`);
*
* // Using the advanced conditions
* const orderedUsers = await query<User>(db, path, advancedConditions);
* console.log(`Found ${orderedUsers.length} users over 25 years old, ordered by name.`);
*
* // Using the limited conditions
* const limitedUsers = await query<User>(db, path, limitedConditions);
* console.log(`Found ${limitedUsers.length} users over 25 years old, limited to 5.`);
*
* } catch (error) {
* console.error(`Error querying collection: ${error}`);
* }
* }
*
* run();
* ```
*/
export const queryCollectionItems = async <T extends firestore.DocumentData>(
db: firestore.Firestore,
collectionPath: string,
conditions: QueryCondition[]
): Promise<T[]> => {
try {
let query: firestore.Query = db
.collection(collectionPath)
.withConverter(createFirestoreDataConverter<T>())
for (const condition of conditions) {
if (
condition.field &&
condition.operator &&
condition.value !== undefined
) {
query = query.where(
condition.field,
condition.operator,
condition.value
)
}
if (condition.field && condition.orderDirection) {
query = query.orderBy(condition.field, condition.orderDirection)
}
if (condition.limit !== undefined) {
query = query.limit(condition.limit)
}
}
const snapshot = await query.get()
return snapshot.docs.map((doc) => ({
id: doc.id,
...(doc.data() as T),
}))
} catch (error) {
throw new Error(`Error querying collection: ${error}`)
}
}