@@ -2,7 +2,7 @@ import 'dart:async';
22
33import 'package:cloud_firestore/cloud_firestore.dart' ;
44import 'package:codelessly_api/codelessly_api.dart' ;
5- import 'package:flutter/cupertino .dart' ;
5+ import 'package:flutter/widgets .dart' ;
66
77import '../../codelessly_sdk.dart' ;
88import '../utils/constants.dart' ;
@@ -41,6 +41,8 @@ abstract class CloudDatabase extends ChangeNotifier {
4141 /// This cannot be an empty string.
4242 final String identifier;
4343
44+ /// The source of the publish, this is used to determine the root collection
45+ /// to use for the cloud database.
4446 final PublishSource publishSource;
4547
4648 /// Creates a new instance of with the given [identifier] .
@@ -195,12 +197,20 @@ class FirestoreCloudDatabase extends CloudDatabase {
195197 /// Reference to the Firestore instance.
196198 final FirebaseFirestore firestore;
197199
200+ /// Reference to the StatTracker instance, used to track reads and writes.
201+ final StatTracker tracker;
202+
198203 /// Subscriptions to the streams that are being listened to.
199204 final List <StreamSubscription > _subscriptions = [];
200205
201206 /// Creates a [FirestoreCloudDatabase] with the given [identifier] and
202207 /// [firestore] instance.
203- FirestoreCloudDatabase (super .identifier, this .firestore, super .publishSource);
208+ FirestoreCloudDatabase (
209+ super .identifier,
210+ super .publishSource, {
211+ required this .firestore,
212+ required this .tracker,
213+ });
204214
205215 void log (String message) => logger.log (_label, message);
206216
@@ -213,12 +223,14 @@ class FirestoreCloudDatabase extends CloudDatabase {
213223
214224 // Create project doc if missing.
215225 final snapshot = await rootRef.get ();
226+ tracker.trackRead ();
216227
217228 // Do nothing if project doc exists.
218229 if (snapshot.exists) return ;
219230
220231 // Create project doc if it does not exist.
221232 await rootRef.set ({'project' : identifier});
233+ tracker.trackWrite ();
222234
223235 logger.log (_label, 'Done initializing for $identifier ' );
224236 }
@@ -295,6 +307,8 @@ class FirestoreCloudDatabase extends CloudDatabase {
295307 if (autoGenerateId) {
296308 // if autoGenerateId is true, then skipCreationIfDocumentExists and docId is ignored.
297309 final document = await rootRef.collection (path).add (value);
310+ tracker.trackWrite ();
311+
298312 logger.log (_label, 'Document added: ${document .path }' );
299313
300314 // Sanitize data afterwards because we didn't have the docId before.
@@ -313,6 +327,8 @@ class FirestoreCloudDatabase extends CloudDatabase {
313327
314328 // Get snapshot to check if document exists.
315329 final snapshot = await docRef.get ();
330+ tracker.trackRead ();
331+
316332 if (skipCreationIfDocumentExists && snapshot.exists) {
317333 // if skipCreationIfDocumentExists is true, check if document exists.
318334 // if document exists, then return.
@@ -322,6 +338,8 @@ class FirestoreCloudDatabase extends CloudDatabase {
322338
323339 // Set document.
324340 await docRef.set (value);
341+ tracker.trackWrite ();
342+
325343 logger.log (_label, 'Document added: ${docRef .path }/$documentId ' );
326344 return true ;
327345 }
@@ -344,36 +362,50 @@ class FirestoreCloudDatabase extends CloudDatabase {
344362
345363 // TODO: Should we do update instead of set?
346364 await docRef.set (value, SetOptions (merge: true ));
365+ tracker.trackWrite ();
366+
347367 logger.log (_label, 'Document updated: ${docRef .path }' );
348368 return true ;
349369 }
350370
351371 @override
352372 Future <bool > removeDocument (String path, String documentId) async {
353373 final docRef = getDocPath (path, documentId);
374+
354375 final snapshot = await docRef.get ();
376+ tracker.trackRead ();
377+
355378 // TODO: Do we have to check for existence?
356379 if (! snapshot.exists) return false ;
380+
357381 await docRef.delete ();
382+ tracker.trackWrite ();
383+
358384 return true ;
359385 }
360386
361387 @override
362388 Future <Map <String , dynamic >> getDocumentData (
363389 String path, String documentId) async {
364390 final docRef = getDocPath (path, documentId);
391+
365392 final snapshot = await docRef.get ();
393+ tracker.trackRead ();
394+
366395 final data = snapshot.data () ?? {};
367396 return sanitizeCloudDataForUse (data, docId: snapshot.id);
368397 }
369398
370399 @override
371400 Stream <Map <String , dynamic >> streamDocument (String path, String documentId) {
372401 final docRef = getDocPath (path, documentId);
373- return docRef.snapshots ().map ((snapshot) =>
374- snapshot.data ()? .let (
375- (value) => sanitizeCloudDataForUse (value, docId: snapshot.id)) ??
376- {});
402+ return docRef.snapshots ().map ((snapshot) {
403+ tracker.trackRead ();
404+
405+ return snapshot.data ()? .let (
406+ (value) => sanitizeCloudDataForUse (value, docId: snapshot.id)) ??
407+ {};
408+ });
377409 }
378410
379411 @override
@@ -391,6 +423,8 @@ class FirestoreCloudDatabase extends CloudDatabase {
391423 // Listen to the stream and update the variable.
392424 final subscription = stream.listen (
393425 (data) {
426+ tracker.trackRead ();
427+
394428 logger.log (_label,
395429 'Document stream update from cloud storage: $path /$documentId ' );
396430 logger.log (_label,
@@ -466,6 +500,8 @@ class FirestoreCloudDatabase extends CloudDatabase {
466500 // Listen to the stream and update the variable.
467501 final subscription = stream.listen (
468502 (snapshot) {
503+ tracker.trackRead ();
504+
469505 final docs = snapshot.docs
470506 .map ((doc) => sanitizeCloudDataForUse (doc.data (), docId: doc.id))
471507 .toList ();
0 commit comments