@umituz/react-native-firebase 1.13.49 → 1.13.50

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.
Files changed (54) hide show
  1. package/dist/scripts/cli-handlers.d.ts +27 -0
  2. package/dist/scripts/cli-handlers.d.ts.map +1 -0
  3. package/dist/scripts/cli-handlers.js +125 -0
  4. package/dist/scripts/cli-handlers.js.map +1 -0
  5. package/dist/scripts/cli-parser.d.ts +25 -0
  6. package/dist/scripts/cli-parser.d.ts.map +1 -0
  7. package/dist/scripts/cli-parser.js +101 -0
  8. package/dist/scripts/cli-parser.js.map +1 -0
  9. package/dist/scripts/cli.js +20 -155
  10. package/dist/scripts/cli.js.map +1 -1
  11. package/dist/scripts/firestore-operations.d.ts +18 -0
  12. package/dist/scripts/firestore-operations.d.ts.map +1 -0
  13. package/dist/scripts/firestore-operations.js +88 -0
  14. package/dist/scripts/firestore-operations.js.map +1 -0
  15. package/dist/scripts/firestore-queries.d.ts +27 -0
  16. package/dist/scripts/firestore-queries.d.ts.map +1 -0
  17. package/dist/scripts/firestore-queries.js +77 -0
  18. package/dist/scripts/firestore-queries.js.map +1 -0
  19. package/dist/scripts/firestore-seeding.d.ts +21 -0
  20. package/dist/scripts/firestore-seeding.d.ts.map +1 -0
  21. package/dist/scripts/firestore-seeding.js +67 -0
  22. package/dist/scripts/firestore-seeding.js.map +1 -0
  23. package/dist/scripts/firestore.d.ts +3 -48
  24. package/dist/scripts/firestore.d.ts.map +1 -1
  25. package/dist/scripts/firestore.js +16 -210
  26. package/dist/scripts/firestore.js.map +1 -1
  27. package/dist/scripts/user-commands.d.ts +33 -0
  28. package/dist/scripts/user-commands.d.ts.map +1 -0
  29. package/dist/scripts/user-commands.js +113 -0
  30. package/dist/scripts/user-commands.js.map +1 -0
  31. package/dist/scripts/user-formatters.d.ts +10 -0
  32. package/dist/scripts/user-formatters.d.ts.map +1 -0
  33. package/dist/scripts/user-formatters.js +55 -0
  34. package/dist/scripts/user-formatters.js.map +1 -0
  35. package/dist/scripts/user-queries.d.ts +42 -0
  36. package/dist/scripts/user-queries.d.ts.map +1 -0
  37. package/dist/scripts/user-queries.js +125 -0
  38. package/dist/scripts/user-queries.js.map +1 -0
  39. package/dist/scripts/user.d.ts +3 -67
  40. package/dist/scripts/user.d.ts.map +1 -1
  41. package/dist/scripts/user.js +15 -272
  42. package/dist/scripts/user.js.map +1 -1
  43. package/package.json +1 -1
  44. package/scripts/cli-handlers.ts +170 -0
  45. package/scripts/cli-parser.ts +82 -0
  46. package/scripts/cli.ts +27 -193
  47. package/scripts/firestore-operations.ts +111 -0
  48. package/scripts/firestore-queries.ts +97 -0
  49. package/scripts/firestore-seeding.ts +87 -0
  50. package/scripts/firestore.ts +20 -275
  51. package/scripts/user-commands.ts +104 -0
  52. package/scripts/user-formatters.ts +55 -0
  53. package/scripts/user-queries.ts +185 -0
  54. package/scripts/user.ts +19 -326
@@ -3,278 +3,23 @@
3
3
  * Generic Firestore operations for admin scripts
4
4
  */
5
5
 
6
- import * as admin from "firebase-admin";
7
- import type { CollectionInfo, BatchResult } from "./types";
8
-
9
- const BATCH_SIZE = 500;
10
-
11
- /**
12
- * List all root-level collections
13
- */
14
- export async function listCollections(
15
- db: admin.firestore.Firestore
16
- ): Promise<CollectionInfo[]> {
17
- const collections = await db.listCollections();
18
- const result: CollectionInfo[] = [];
19
-
20
- for (const collection of collections) {
21
- const snapshot = await collection.limit(1000).get();
22
- const info: CollectionInfo = {
23
- name: collection.id,
24
- documentCount: snapshot.docs.length,
25
- sampleDocumentId: snapshot.docs[0]?.id,
26
- };
27
-
28
- if (!snapshot.empty) {
29
- const subcollections = await snapshot.docs[0].ref.listCollections();
30
- info.hasSubcollections = subcollections.length > 0;
31
- }
32
-
33
- result.push(info);
34
- }
35
-
36
- return result.sort((a, b) => b.documentCount - a.documentCount);
37
- }
38
-
39
- /**
40
- * List subcollections for a user document
41
- */
42
- export async function listUserSubcollections(
43
- db: admin.firestore.Firestore,
44
- userId: string
45
- ): Promise<CollectionInfo[]> {
46
- const userRef = db.collection("users").doc(userId);
47
- const subcollections = await userRef.listCollections();
48
- const result: CollectionInfo[] = [];
49
-
50
- for (const subcollection of subcollections) {
51
- const count = await subcollection.count().get();
52
- result.push({
53
- name: subcollection.id,
54
- documentCount: count.data().count,
55
- });
56
- }
57
-
58
- return result;
59
- }
60
-
61
- /**
62
- * Delete collection in batches
63
- */
64
- export async function deleteCollection(
65
- db: admin.firestore.Firestore,
66
- collectionPath: string,
67
- onProgress?: (deleted: number) => void
68
- ): Promise<number> {
69
- let totalDeleted = 0;
70
- let hasMore = true;
71
-
72
- while (hasMore) {
73
- const snapshot = await db
74
- .collection(collectionPath)
75
- .orderBy("__name__")
76
- .limit(BATCH_SIZE)
77
- .get();
78
-
79
- if (snapshot.empty) {
80
- hasMore = false;
81
- continue;
82
- }
83
-
84
- const batch = db.batch();
85
- snapshot.docs.forEach((doc) => batch.delete(doc.ref));
86
- await batch.commit();
87
-
88
- totalDeleted += snapshot.docs.length;
89
- onProgress?.(totalDeleted);
90
- }
91
-
92
- return totalDeleted;
93
- }
94
-
95
- /**
96
- * Delete user subcollection for all users
97
- */
98
- export async function deleteUserSubcollection(
99
- db: admin.firestore.Firestore,
100
- subcollectionName: string,
101
- onProgress?: (deleted: number) => void
102
- ): Promise<number> {
103
- let totalDeleted = 0;
104
- const usersSnapshot = await db.collection("users").get();
105
-
106
- for (const userDoc of usersSnapshot.docs) {
107
- const subcollectionRef = userDoc.ref.collection(subcollectionName);
108
- const subcollectionSnapshot = await subcollectionRef.get();
109
-
110
- if (!subcollectionSnapshot.empty) {
111
- const batch = db.batch();
112
- subcollectionSnapshot.docs.forEach((doc) => batch.delete(doc.ref));
113
- await batch.commit();
114
- totalDeleted += subcollectionSnapshot.docs.length;
115
- onProgress?.(totalDeleted);
116
- }
117
- }
118
-
119
- return totalDeleted;
120
- }
121
-
122
- /**
123
- * Delete all Firestore data
124
- */
125
- export async function deleteAllData(
126
- db: admin.firestore.Firestore,
127
- onProgress?: (collection: string, deleted: number) => void
128
- ): Promise<number> {
129
- let totalDeleted = 0;
130
- const collections = await db.listCollections();
131
-
132
- for (const collection of collections) {
133
- const snapshot = await collection.get();
134
-
135
- // Delete subcollections first for users collection
136
- if (collection.id === "users") {
137
- for (const doc of snapshot.docs) {
138
- const subcollections = await doc.ref.listCollections();
139
- for (const subcollection of subcollections) {
140
- const subSnapshot = await subcollection.get();
141
- if (!subSnapshot.empty) {
142
- const batch = db.batch();
143
- subSnapshot.docs.forEach((subDoc) => batch.delete(subDoc.ref));
144
- await batch.commit();
145
- totalDeleted += subSnapshot.docs.length;
146
- }
147
- }
148
- }
149
- }
150
-
151
- // Delete main collection documents
152
- if (!snapshot.empty) {
153
- const batch = db.batch();
154
- snapshot.docs.forEach((doc) => batch.delete(doc.ref));
155
- await batch.commit();
156
- totalDeleted += snapshot.docs.length;
157
- onProgress?.(collection.id, totalDeleted);
158
- }
159
- }
160
-
161
- return totalDeleted;
162
- }
163
-
164
- /**
165
- * Seed documents in batches
166
- */
167
- export async function seedBatch(
168
- db: admin.firestore.Firestore,
169
- collectionPath: string,
170
- docs: Array<{ id: string; data: Record<string, unknown> }>
171
- ): Promise<BatchResult> {
172
- const result: BatchResult = {
173
- success: true,
174
- processed: 0,
175
- errors: [],
176
- };
177
-
178
- for (let i = 0; i < docs.length; i += BATCH_SIZE) {
179
- const batch = db.batch();
180
- const slice = docs.slice(i, i + BATCH_SIZE);
181
-
182
- for (const { id, data } of slice) {
183
- const ref = db.collection(collectionPath).doc(id);
184
- const clean = Object.fromEntries(
185
- Object.entries(data).filter(([, v]) => v !== undefined)
186
- );
187
- batch.set(ref, clean);
188
- }
189
-
190
- try {
191
- await batch.commit();
192
- result.processed += slice.length;
193
- } catch (error) {
194
- result.success = false;
195
- result.errors.push(`Batch failed at index ${i}: ${error}`);
196
- }
197
- }
198
-
199
- return result;
200
- }
201
-
202
- /**
203
- * Seed user subcollection
204
- */
205
- export async function seedUserSubcollection(
206
- db: admin.firestore.Firestore,
207
- userId: string,
208
- subcollectionName: string,
209
- docs: Array<{ id: string; data: Record<string, unknown> }>
210
- ): Promise<BatchResult> {
211
- const result: BatchResult = {
212
- success: true,
213
- processed: 0,
214
- errors: [],
215
- };
216
-
217
- const batch = db.batch();
218
-
219
- for (const { id, data } of docs) {
220
- const ref = db
221
- .collection("users")
222
- .doc(userId)
223
- .collection(subcollectionName)
224
- .doc(id);
225
- const clean = Object.fromEntries(
226
- Object.entries(data).filter(([, v]) => v !== undefined)
227
- );
228
- batch.set(ref, clean);
229
- }
230
-
231
- try {
232
- await batch.commit();
233
- result.processed = docs.length;
234
- } catch (error) {
235
- result.success = false;
236
- result.errors.push(`Failed to seed subcollection: ${error}`);
237
- }
238
-
239
- return result;
240
- }
241
-
242
- /**
243
- * Count documents in collection
244
- */
245
- export async function countDocuments(
246
- db: admin.firestore.Firestore,
247
- collectionPath: string
248
- ): Promise<number> {
249
- const count = await db.collection(collectionPath).count().get();
250
- return count.data().count;
251
- }
252
-
253
- /**
254
- * Get user document count statistics
255
- */
256
- export async function getUserStats(db: admin.firestore.Firestore): Promise<{
257
- total: number;
258
- anonymous: number;
259
- authenticated: number;
260
- }> {
261
- const usersSnapshot = await db.collection("users").get();
262
-
263
- let anonymous = 0;
264
- let authenticated = 0;
265
-
266
- usersSnapshot.docs.forEach((doc) => {
267
- const data = doc.data();
268
- if (data.isAnonymous) {
269
- anonymous++;
270
- } else {
271
- authenticated++;
272
- }
273
- });
274
-
275
- return {
276
- total: usersSnapshot.docs.length,
277
- anonymous,
278
- authenticated,
279
- };
280
- }
6
+ // Query functions
7
+ export {
8
+ listCollections,
9
+ listUserSubcollections,
10
+ countDocuments,
11
+ getUserStats,
12
+ } from "./firestore-queries";
13
+
14
+ // Delete operations
15
+ export {
16
+ deleteCollection,
17
+ deleteUserSubcollection,
18
+ deleteAllData,
19
+ } from "./firestore-operations";
20
+
21
+ // Seed operations
22
+ export {
23
+ seedBatch,
24
+ seedUserSubcollection,
25
+ } from "./firestore-seeding";
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Firebase Admin User Commands
3
+ * Command functions for modifying user data
4
+ */
5
+
6
+ import * as admin from "firebase-admin";
7
+ import type { UserCredits, CreditsConfig } from "./types";
8
+
9
+ /**
10
+ * Initialize credits for a user
11
+ */
12
+ export async function initializeUserCredits(
13
+ db: admin.firestore.Firestore,
14
+ userId: string,
15
+ config: CreditsConfig
16
+ ): Promise<UserCredits> {
17
+ const { collectionName = "user_credits", textLimit = 0, imageLimit = 0 } = config;
18
+
19
+ const now = admin.firestore.FieldValue.serverTimestamp();
20
+
21
+ const credits: Omit<UserCredits, "createdAt" | "updatedAt"> & {
22
+ createdAt: admin.firestore.FieldValue;
23
+ updatedAt: admin.firestore.FieldValue;
24
+ } = {
25
+ text: textLimit,
26
+ image: imageLimit,
27
+ video: 0,
28
+ audio: 0,
29
+ createdAt: now,
30
+ updatedAt: now,
31
+ };
32
+
33
+ await db.collection(collectionName).doc(userId).set(credits, { merge: true });
34
+
35
+ return {
36
+ text: textLimit,
37
+ image: imageLimit,
38
+ video: 0,
39
+ audio: 0,
40
+ createdAt: new Date(),
41
+ updatedAt: new Date(),
42
+ };
43
+ }
44
+
45
+ /**
46
+ * Add credits to a user
47
+ */
48
+ export async function addUserCredits(
49
+ db: admin.firestore.Firestore,
50
+ userId: string,
51
+ credits: { text?: number; image?: number; video?: number; audio?: number },
52
+ collectionName = "user_credits"
53
+ ): Promise<void> {
54
+ const updates: Record<string, admin.firestore.FieldValue> = {
55
+ updatedAt: admin.firestore.FieldValue.serverTimestamp(),
56
+ };
57
+
58
+ if (credits.text) {
59
+ updates.text = admin.firestore.FieldValue.increment(credits.text);
60
+ }
61
+ if (credits.image) {
62
+ updates.image = admin.firestore.FieldValue.increment(credits.image);
63
+ }
64
+ if (credits.video) {
65
+ updates.video = admin.firestore.FieldValue.increment(credits.video);
66
+ }
67
+ if (credits.audio) {
68
+ updates.audio = admin.firestore.FieldValue.increment(credits.audio);
69
+ }
70
+
71
+ await db.collection(collectionName).doc(userId).update(updates);
72
+ }
73
+
74
+ /**
75
+ * Set credits for a user (overwrite)
76
+ */
77
+ export async function setUserCredits(
78
+ db: admin.firestore.Firestore,
79
+ userId: string,
80
+ credits: { text?: number; image?: number; video?: number; audio?: number },
81
+ collectionName = "user_credits"
82
+ ): Promise<void> {
83
+ const updates: Record<string, unknown> = {
84
+ updatedAt: admin.firestore.FieldValue.serverTimestamp(),
85
+ };
86
+
87
+ if (credits.text !== undefined) updates.text = credits.text;
88
+ if (credits.image !== undefined) updates.image = credits.image;
89
+ if (credits.video !== undefined) updates.video = credits.video;
90
+ if (credits.audio !== undefined) updates.audio = credits.audio;
91
+
92
+ await db.collection(collectionName).doc(userId).set(updates, { merge: true });
93
+ }
94
+
95
+ /**
96
+ * Delete user credits document
97
+ */
98
+ export async function deleteUserCredits(
99
+ db: admin.firestore.Firestore,
100
+ userId: string,
101
+ collectionName = "user_credits"
102
+ ): Promise<void> {
103
+ await db.collection(collectionName).doc(userId).delete();
104
+ }
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Firebase Admin User Formatters
3
+ * Format functions for displaying user data
4
+ */
5
+
6
+ import type { UserData } from "./types";
7
+
8
+ /**
9
+ * Print user data in formatted way
10
+ */
11
+ export function printUserData(data: UserData): void {
12
+ console.log("\n" + "═".repeat(60));
13
+ console.log(`👤 USER: ${data.userId}`);
14
+ console.log("═".repeat(60));
15
+
16
+ console.log("\n📋 PROFILE:");
17
+ if (data.profile) {
18
+ console.log(JSON.stringify(data.profile, null, 2));
19
+ } else {
20
+ console.log(" ❌ Not found");
21
+ }
22
+
23
+ console.log("\n💰 CREDITS:");
24
+ if (data.credits) {
25
+ console.log(` Text: ${data.credits.text || 0}`);
26
+ console.log(` Image: ${data.credits.image || 0}`);
27
+ console.log(` Video: ${data.credits.video || 0}`);
28
+ console.log(` Audio: ${data.credits.audio || 0}`);
29
+ } else {
30
+ console.log(" ❌ Not found");
31
+ }
32
+
33
+ console.log("\n🔔 SUBSCRIPTIONS:");
34
+ if (data.subscriptions.length > 0) {
35
+ data.subscriptions.forEach((sub) => {
36
+ console.log(` - ${sub.id}: ${JSON.stringify(sub)}`);
37
+ });
38
+ } else {
39
+ console.log(" ❌ None");
40
+ }
41
+
42
+ console.log("\n🧾 TRANSACTIONS:");
43
+ if (data.transactions.length > 0) {
44
+ data.transactions.slice(0, 5).forEach((tx) => {
45
+ console.log(` - ${tx.id}: ${JSON.stringify(tx)}`);
46
+ });
47
+ if (data.transactions.length > 5) {
48
+ console.log(` ... and ${data.transactions.length - 5} more`);
49
+ }
50
+ } else {
51
+ console.log(" ❌ None");
52
+ }
53
+
54
+ console.log("\n" + "═".repeat(60) + "\n");
55
+ }
@@ -0,0 +1,185 @@
1
+ /**
2
+ * Firebase Admin User Queries
3
+ * Query functions for reading user data
4
+ */
5
+
6
+ import * as admin from "firebase-admin";
7
+ import type { UserData, UserCredits } from "./types";
8
+
9
+ /**
10
+ * Get complete user data including profile and all related collections
11
+ */
12
+ export async function getUserData(
13
+ db: admin.firestore.Firestore,
14
+ userId: string,
15
+ options?: {
16
+ includeCredits?: boolean;
17
+ includeSubscriptions?: boolean;
18
+ includeTransactions?: boolean;
19
+ creditsCollection?: string;
20
+ }
21
+ ): Promise<UserData> {
22
+ const {
23
+ includeCredits = true,
24
+ includeSubscriptions = true,
25
+ includeTransactions = true,
26
+ creditsCollection = "user_credits",
27
+ } = options || {};
28
+
29
+ const result: UserData = {
30
+ userId,
31
+ exists: false,
32
+ profile: null,
33
+ credits: null,
34
+ subscriptions: [],
35
+ transactions: [],
36
+ };
37
+
38
+ // Get user profile
39
+ const userDoc = await db.collection("users").doc(userId).get();
40
+ if (userDoc.exists) {
41
+ result.exists = true;
42
+ result.profile = userDoc.data() as Record<string, unknown>;
43
+ }
44
+
45
+ // Get credits from root-level collection
46
+ if (includeCredits) {
47
+ const creditsDoc = await db.collection(creditsCollection).doc(userId).get();
48
+ if (creditsDoc.exists) {
49
+ result.credits = creditsDoc.data() as UserCredits;
50
+ }
51
+ }
52
+
53
+ // Get subscriptions subcollection
54
+ if (includeSubscriptions) {
55
+ const subsSnapshot = await db
56
+ .collection("users")
57
+ .doc(userId)
58
+ .collection("subscriptions")
59
+ .get();
60
+ result.subscriptions = subsSnapshot.docs.map((doc) => ({
61
+ id: doc.id,
62
+ ...doc.data(),
63
+ }));
64
+ }
65
+
66
+ // Get transactions subcollection
67
+ if (includeTransactions) {
68
+ const txSnapshot = await db
69
+ .collection("users")
70
+ .doc(userId)
71
+ .collection("transactions")
72
+ .orderBy("createdAt", "desc")
73
+ .limit(50)
74
+ .get();
75
+ result.transactions = txSnapshot.docs.map((doc) => ({
76
+ id: doc.id,
77
+ ...doc.data(),
78
+ }));
79
+ }
80
+
81
+ return result;
82
+ }
83
+
84
+ /**
85
+ * List all users with their credit balances
86
+ */
87
+ export async function listUsersWithCredits(
88
+ db: admin.firestore.Firestore,
89
+ options?: {
90
+ creditsCollection?: string;
91
+ limit?: number;
92
+ onlyWithCredits?: boolean;
93
+ }
94
+ ): Promise<
95
+ Array<{
96
+ userId: string;
97
+ displayName?: string;
98
+ email?: string;
99
+ isAnonymous: boolean;
100
+ credits: UserCredits | null;
101
+ }>
102
+ > {
103
+ const { creditsCollection = "user_credits", limit = 100, onlyWithCredits = false } = options || {};
104
+
105
+ const usersSnapshot = await db.collection("users").limit(limit).get();
106
+ const result: Array<{
107
+ userId: string;
108
+ displayName?: string;
109
+ email?: string;
110
+ isAnonymous: boolean;
111
+ credits: UserCredits | null;
112
+ }> = [];
113
+
114
+ for (const userDoc of usersSnapshot.docs) {
115
+ const userData = userDoc.data();
116
+ const creditsDoc = await db.collection(creditsCollection).doc(userDoc.id).get();
117
+ const credits = creditsDoc.exists ? (creditsDoc.data() as UserCredits) : null;
118
+
119
+ if (onlyWithCredits && !credits) continue;
120
+
121
+ result.push({
122
+ userId: userDoc.id,
123
+ displayName: userData.displayName,
124
+ email: userData.email,
125
+ isAnonymous: userData.isAnonymous || false,
126
+ credits,
127
+ });
128
+ }
129
+
130
+ return result;
131
+ }
132
+
133
+ /**
134
+ * Get credits summary across all users
135
+ */
136
+ export async function getCreditsSummary(
137
+ db: admin.firestore.Firestore,
138
+ collectionName = "user_credits"
139
+ ): Promise<{
140
+ totalUsers: number;
141
+ totalText: number;
142
+ totalImage: number;
143
+ totalVideo: number;
144
+ totalAudio: number;
145
+ usersWithCredits: number;
146
+ usersWithZeroCredits: number;
147
+ }> {
148
+ const snapshot = await db.collection(collectionName).get();
149
+
150
+ let totalText = 0;
151
+ let totalImage = 0;
152
+ let totalVideo = 0;
153
+ let totalAudio = 0;
154
+ let usersWithCredits = 0;
155
+ let usersWithZeroCredits = 0;
156
+
157
+ snapshot.docs.forEach((doc) => {
158
+ const data = doc.data();
159
+ const text = data.text || 0;
160
+ const image = data.image || 0;
161
+ const video = data.video || 0;
162
+ const audio = data.audio || 0;
163
+
164
+ totalText += text;
165
+ totalImage += image;
166
+ totalVideo += video;
167
+ totalAudio += audio;
168
+
169
+ if (text > 0 || image > 0 || video > 0 || audio > 0) {
170
+ usersWithCredits++;
171
+ } else {
172
+ usersWithZeroCredits++;
173
+ }
174
+ });
175
+
176
+ return {
177
+ totalUsers: snapshot.docs.length,
178
+ totalText,
179
+ totalImage,
180
+ totalVideo,
181
+ totalAudio,
182
+ usersWithCredits,
183
+ usersWithZeroCredits,
184
+ };
185
+ }