Advertisement
Guest User

Firebase Cache system

a guest
Jan 27th, 2025
165
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 7.09 KB | None | 0 0
  1. Future<List> getFirestoreDataOptimized(bool fetchCache, Query ref, bool filterDeleted, bool filterSubscribed, Event event) async {
  2.     // Get Cache data first if it exists
  3.     List data = [];
  4.  
  5.     //! START CACHE SYSTEM
  6.     if (fetchCache == true && event.disableCache == false) {
  7.       // Count the number of documents that the query should return from the server
  8.       AggregateQuerySnapshot query = await ref.count().get();
  9.       int correctDocumentCount = query.count ?? 0;
  10.  
  11.       var snapshot = await ref.getCacheFirst();
  12.  
  13.       var documents = snapshot.docs.map((s) => s);
  14.       for (QueryDocumentSnapshot element in documents) {
  15.         Map documentData = element.data() as Map<String, dynamic>;
  16.  
  17.         documentData['documentId'] = element.id;
  18.         data.add(documentData);
  19.       }
  20.  
  21.       // Check if the number of documents returned from the server is the same as the number of documents in the cache
  22.       debugPrint('DEBUG - Cache document count: ${data.length} - Server document count: $correctDocumentCount');
  23.       if (data.length != correctDocumentCount) {
  24.         List freshData = [];
  25.         debugPrint('DEBUG - Cache ignored due to document count conflict');
  26.         //fetchCache = false;
  27.         var snapshot = await ref.get();
  28.         var documents = snapshot.docs.map((s) => s);
  29.         for (QueryDocumentSnapshot element in documents) {
  30.           Map documentData = element.data() as Map<String, dynamic>;
  31.  
  32.           documentData['documentId'] = element.id;
  33.           freshData.add(documentData);
  34.         }
  35.         // Overwrite cache data with fresh data
  36.         data = freshData;
  37.         debugPrint('DEBUG - Overwrote cache data with fresh data');
  38.       }
  39.  
  40.       /// CACHE SYSTEM
  41.       // Check if there is any newer data on the server and get new data if so.
  42.  
  43.       // Get last timestamp from cached data
  44.       debugPrint('DEBUG - Checking for new data from server to update cache if needed');
  45.       Timestamp lastUpdate = Timestamp(0, 0);
  46.       for (var element in data) {
  47.         if (element.containsKey('updated') && element['documentId'] == AuthService().user!.uid) {
  48.           debugPrint('DEBUG - Cache Timestamp ignored due to potential timestamp conflict with User for ${ref.toString()}');
  49.         }
  50.         // Only use the timestamp if the documentId does not equal UID
  51.         if (element.containsKey('updated') && element['documentId'] != AuthService().user!.uid) {
  52.           if (element['updated'] is Timestamp) {
  53.             Timestamp timeStamp = element['updated'];
  54.  
  55.             if (timeStamp.compareTo(lastUpdate) >= 0) {
  56.               lastUpdate = timeStamp;
  57.             }
  58.           } else if (element['updated'] == null) {
  59.             // Do nothing
  60.           } else {
  61.             Timestamp newTimeStamp = Timestamp(element['updated'].round(), 0);
  62.             if (newTimeStamp.compareTo(lastUpdate) >= 0) {
  63.               lastUpdate = newTimeStamp;
  64.             }
  65.           }
  66.         }
  67.       }
  68.       List newData = [];
  69.  
  70.       var updateRef = ref.where('updated', isGreaterThan: lastUpdate);
  71.       var newSnapshot = await updateRef.get();
  72.       var newDocuments = newSnapshot.docs.map((s) => s);
  73.       for (QueryDocumentSnapshot element in newDocuments) {
  74.         Map documentData = element.data() as Map<String, dynamic>;
  75.         documentData['documentId'] = element.id;
  76.         newData.add(documentData);
  77.       }
  78.       // Merge old and new data if there are any new additions or updates
  79.       if (newData.isNotEmpty) {
  80.         for (var newDocument in newData) {
  81.           // Check if it exists in cache data
  82.           if (data.any((element) => element['documentId'] == newDocument['documentId'])) {
  83.             // Replace data with new version from server
  84.             var index = data.indexWhere((element) => element['documentId'] == newDocument['documentId']);
  85.             data[index] = newDocument;
  86.             debugPrint('DEBUG CACHE - Updated cache document with new data from server');
  87.           } else {
  88.             data.add(newDocument);
  89.             debugPrint('DEBUG CACHE - New document added to cache');
  90.           }
  91.         }
  92.       }
  93.     } else {
  94.       var snapshot = await ref.get();
  95.       var documents = snapshot.docs.map((s) => s);
  96.       for (QueryDocumentSnapshot element in documents) {
  97.         Map documentData = element.data() as Map<String, dynamic>;
  98.  
  99.         documentData['documentId'] = element.id;
  100.         data.add(documentData);
  101.       }
  102.     }
  103.     //! START FILTER SYSTEM
  104.  
  105.     // Filter data if needed
  106.     if (filterDeleted) {
  107.       List filteredData = [];
  108.       for (var element in data) {
  109.         if (element['deleted'] == false) {
  110.           filteredData.add(element);
  111.         }
  112.       }
  113.       data = filteredData;
  114.     }
  115.     // FIX subscription
  116.     if (filterSubscribed) {
  117.       List filteredData = [];
  118.       for (var element in data) {
  119.         if (element.containsKey('subscribers')) {
  120.           if (element['subscribers'].contains(AuthService().user!.uid)) {
  121.             element['subscribed'] = true;
  122.             debugPrint('Got subscribed document ${element['documentId']}');
  123.             filteredData.add(element);
  124.           }
  125.         }
  126.       }
  127.       // replace data with filtered data to only show subscribed elements
  128.       data = filteredData;
  129.     } else {
  130.       for (var element in data) {
  131.         if (element.containsKey('subscribers')) {
  132.           if (element['subscribers'].contains(AuthService().user!.uid)) {
  133.             element['subscribed'] = true;
  134.             debugPrint('Got subscribed document ${element['documentId']}');
  135.           } else {
  136.             element['subscribed'] = false;
  137.           }
  138.         }
  139.       }
  140.     }
  141.  
  142.     // Return early if empty
  143.     if (data.isEmpty) {
  144.       return data;
  145.     }
  146.  
  147.     if (data.first.containsKey('date') && data.first.containsKey('timeStart')) {
  148.       // Sort by date and time
  149.       data.sort((a, b) {
  150.         int compare = a['date'].compareTo(b['date']);
  151.  
  152.         if (compare == 0) {
  153.           var timeList1 = a['timeStart'].split(':');
  154.           var timeList2 = b['timeStart'].split(':');
  155.           int x = int.parse(timeList1[0]) * 60 + int.parse(timeList1[1]);
  156.           int y = int.parse(timeList2[0]) * 60 + int.parse(timeList2[1]);
  157.  
  158.           return x.compareTo(y);
  159.         } else {
  160.           return compare;
  161.         }
  162.       });
  163.     } else {
  164.       // Sort by name if no date and time
  165.       if (data.isNotEmpty && data.first.containsKey('name')) {
  166.         data.sort((a, b) {
  167.           return a['name'].compareTo(b['name']);
  168.         });
  169.       }
  170.     }
  171.  
  172.     return data;
  173.   }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement