From 06d06da9c837c58d8faa6450c555a24ce8ab39e4 Mon Sep 17 00:00:00 2001 From: Neelkanth Kaushik Date: Tue, 16 Sep 2025 11:52:11 +0530 Subject: [PATCH 1/4] Replaced getApplicationDocumentsDirectory() with getApplicationSupportDirectory in io.dart --- packages/core/lib/utils/store/io.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/lib/utils/store/io.dart b/packages/core/lib/utils/store/io.dart index f93b53d..3b34137 100644 --- a/packages/core/lib/utils/store/io.dart +++ b/packages/core/lib/utils/store/io.dart @@ -90,7 +90,7 @@ class StoreImpl with Store { Future _getDocumentDir() async { try { - return await getApplicationDocumentsDirectory(); + return await getApplicationSupportDirectory(); } catch (err) { throw PlatformNotSupportedError(); } From bddb8601c8ae87a5cfa434f24a15de55c8b8cbcf Mon Sep 17 00:00:00 2001 From: Neelkanth Kaushik Date: Mon, 22 Sep 2025 12:52:19 +0530 Subject: [PATCH 2/4] Migrating JSON files from old directory to new location --- packages/core/lib/utils/store/io.dart | 71 ++++++++++++++++++++++++--- 1 file changed, 63 insertions(+), 8 deletions(-) diff --git a/packages/core/lib/utils/store/io.dart b/packages/core/lib/utils/store/io.dart index 3b34137..91810f4 100644 --- a/packages/core/lib/utils/store/io.dart +++ b/packages/core/lib/utils/store/io.dart @@ -10,19 +10,28 @@ import 'package:path_provider/path_provider.dart'; class StoreImpl with Store { final bool storageJson; - StoreImpl({this.storageJson = true}); + late final Future _migrationCompleted; + + StoreImpl({this.storageJson = true}) { + // Start migration immediately but don't block construction + _migrationCompleted = _migrateFilesFromDocumentsToSupport(); + } + @override + Future get ready => Future.value(); + @override - Future?> getPersisted(String key) { + Future?> getPersisted(String key) async { if (!storageJson) return Future.value(null); + // Ensure migration is complete before reading files + await _migrationCompleted; return _readFile(key); } @override - Future get ready => Future.value(); - - @override - Future setPersisted(String key, Map value) { + Future setPersisted(String key, Map value) async { if (!storageJson) return Future.value(); + // Ensure migration is complete before writing files + await _migrationCompleted; return _writeFile(key, value); } @@ -70,7 +79,7 @@ class StoreImpl with Store { } Future _fileName(String fileKey) async { - final path = (await _getDocumentDir()).path; + final path = (await _getNewDocumentDir()).path; return "$path/analytics-flutter-$fileKey.json"; } @@ -88,7 +97,7 @@ class StoreImpl with Store { } } - Future _getDocumentDir() async { + Future _getNewDocumentDir() async { try { return await getApplicationSupportDirectory(); } catch (err) { @@ -96,6 +105,52 @@ class StoreImpl with Store { } } + Future _getOldDocumentDir() async { + try { + return await getApplicationDocumentsDirectory(); + } catch (err) { + throw PlatformNotSupportedError(); + } + } + + /// Migrates existing analytics files from Documents directory to Application Support directory + Future _migrateFilesFromDocumentsToSupport() async { + try { + final oldDir = await _getOldDocumentDir(); + final newDir = await _getNewDocumentDir(); + + // List all analytics files in the old directory + final oldDirFiles = oldDir.listSync() + .whereType() + .where((file) => file.path.contains('analytics-flutter-') && file.path.endsWith('.json')) + .toList(); + + for (final oldFile in oldDirFiles) { + final fileName = oldFile.path.split('/').last; + final newFilePath = '${newDir.path}/$fileName'; + final newFile = File(newFilePath); + + // Only migrate if the file doesn't already exist in the new location + if (!await newFile.exists()) { + try { + // Ensure the new directory exists + await newDir.create(recursive: true); + + // Copy the file to the new location + await oldFile.copy(newFilePath); + + // Delete the old file after successful copy + await oldFile.delete(); + } catch (e) { + // The app should continue to work even if migration fails + } + } + } + } catch (e) { + // Migration failure shouldn't break the app + } + } + @override void dispose() {} } From f78df86c0cf951ff8f9a34a1567a3a155ce80e4f Mon Sep 17 00:00:00 2001 From: Neelkanth Kaushik Date: Tue, 23 Sep 2025 15:43:51 +0530 Subject: [PATCH 3/4] Fixed LIBRARIES-2791 --- .../core/lib/plugins/segment_destination.dart | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/packages/core/lib/plugins/segment_destination.dart b/packages/core/lib/plugins/segment_destination.dart index 501d213..2f1fbe7 100644 --- a/packages/core/lib/plugins/segment_destination.dart +++ b/packages/core/lib/plugins/segment_destination.dart @@ -30,22 +30,31 @@ class SegmentDestination extends DestinationPlugin with Flushable { final List sentEvents = []; var numFailedEvents = 0; + // FIXED: Only dequeue successfully sent events await Future.forEach(chunkedEvents, (batch) async { try { final succeeded = await analytics?.httpClient.startBatchUpload( analytics!.state.configuration.state.writeKey, batch, host: _apiHost); - if (succeeded == null || !succeeded) { + + if (succeeded == true) { + // Only add to sentEvents on actual success + sentEvents.addAll(batch); + } else { numFailedEvents += batch.length; } - sentEvents.addAll(batch); } catch (e) { numFailedEvents += batch.length; - } finally { - _queuePlugin.dequeue(sentEvents); + // Don't add failed events to sentEvents } + // Move dequeue outside finally, after the loop }); + // Only dequeue events that were actually sent successfully + if (sentEvents.isNotEmpty) { + _queuePlugin.dequeue(sentEvents); + } + if (sentEvents.isNotEmpty) { log("Sent ${sentEvents.length} events", kind: LogFilterKind.debug); } From b88cf8e2c2920136444493df4ecae580e586d48e Mon Sep 17 00:00:00 2001 From: Neelkanth Kaushik Date: Tue, 23 Sep 2025 15:50:32 +0530 Subject: [PATCH 4/4] Fixed LIBRARIES-2791 --- packages/core/lib/plugins/segment_destination.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/lib/plugins/segment_destination.dart b/packages/core/lib/plugins/segment_destination.dart index 2f1fbe7..e211ba1 100644 --- a/packages/core/lib/plugins/segment_destination.dart +++ b/packages/core/lib/plugins/segment_destination.dart @@ -30,7 +30,7 @@ class SegmentDestination extends DestinationPlugin with Flushable { final List sentEvents = []; var numFailedEvents = 0; - // FIXED: Only dequeue successfully sent events + // FIXED: Only dequeue successfully sent events await Future.forEach(chunkedEvents, (batch) async { try { final succeeded = await analytics?.httpClient.startBatchUpload(