Skip to content

Commit 5819b25

Browse files
Replaced getApplicationDocumentsDirectory() with getApplicationSupportDirectory in io.dart (#181)
* Replaced getApplicationDocumentsDirectory() with getApplicationSupportDirectory in io.dart * Migrating JSON files from old directory to new location * Fixed LIBRARIES-2791
1 parent ab280b7 commit 5819b25

File tree

2 files changed

+76
-12
lines changed

2 files changed

+76
-12
lines changed

packages/core/lib/plugins/segment_destination.dart

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,22 +30,31 @@ class SegmentDestination extends DestinationPlugin with Flushable {
3030
final List<RawEvent> sentEvents = [];
3131
var numFailedEvents = 0;
3232

33+
// FIXED: Only dequeue successfully sent events
3334
await Future.forEach(chunkedEvents, (batch) async {
3435
try {
3536
final succeeded = await analytics?.httpClient.startBatchUpload(
3637
analytics!.state.configuration.state.writeKey, batch,
3738
host: _apiHost);
38-
if (succeeded == null || !succeeded) {
39+
40+
if (succeeded == true) {
41+
// Only add to sentEvents on actual success
42+
sentEvents.addAll(batch);
43+
} else {
3944
numFailedEvents += batch.length;
4045
}
41-
sentEvents.addAll(batch);
4246
} catch (e) {
4347
numFailedEvents += batch.length;
44-
} finally {
45-
_queuePlugin.dequeue(sentEvents);
48+
// Don't add failed events to sentEvents
4649
}
50+
// Move dequeue outside finally, after the loop
4751
});
4852

53+
// Only dequeue events that were actually sent successfully
54+
if (sentEvents.isNotEmpty) {
55+
_queuePlugin.dequeue(sentEvents);
56+
}
57+
4958
if (sentEvents.isNotEmpty) {
5059
log("Sent ${sentEvents.length} events", kind: LogFilterKind.debug);
5160
}

packages/core/lib/utils/store/io.dart

Lines changed: 63 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,28 @@ import 'package:path_provider/path_provider.dart';
1010

1111
class StoreImpl with Store {
1212
final bool storageJson;
13-
StoreImpl({this.storageJson = true});
13+
late final Future<void> _migrationCompleted;
14+
15+
StoreImpl({this.storageJson = true}) {
16+
// Start migration immediately but don't block construction
17+
_migrationCompleted = _migrateFilesFromDocumentsToSupport();
18+
}
19+
@override
20+
Future get ready => Future.value();
21+
1422
@override
15-
Future<Map<String, dynamic>?> getPersisted(String key) {
23+
Future<Map<String, dynamic>?> getPersisted(String key) async {
1624
if (!storageJson) return Future.value(null);
25+
// Ensure migration is complete before reading files
26+
await _migrationCompleted;
1727
return _readFile(key);
1828
}
1929

2030
@override
21-
Future get ready => Future.value();
22-
23-
@override
24-
Future setPersisted(String key, Map<String, dynamic> value) {
31+
Future setPersisted(String key, Map<String, dynamic> value) async {
2532
if (!storageJson) return Future.value();
33+
// Ensure migration is complete before writing files
34+
await _migrationCompleted;
2635
return _writeFile(key, value);
2736
}
2837

@@ -70,7 +79,7 @@ class StoreImpl with Store {
7079
}
7180

7281
Future<String> _fileName(String fileKey) async {
73-
final path = (await _getDocumentDir()).path;
82+
final path = (await _getNewDocumentDir()).path;
7483
return "$path/analytics-flutter-$fileKey.json";
7584
}
7685

@@ -88,14 +97,60 @@ class StoreImpl with Store {
8897
}
8998
}
9099

91-
Future<Directory> _getDocumentDir() async {
100+
Future<Directory> _getNewDocumentDir() async {
101+
try {
102+
return await getApplicationSupportDirectory();
103+
} catch (err) {
104+
throw PlatformNotSupportedError();
105+
}
106+
}
107+
108+
Future<Directory> _getOldDocumentDir() async {
92109
try {
93110
return await getApplicationDocumentsDirectory();
94111
} catch (err) {
95112
throw PlatformNotSupportedError();
96113
}
97114
}
98115

116+
/// Migrates existing analytics files from Documents directory to Application Support directory
117+
Future<void> _migrateFilesFromDocumentsToSupport() async {
118+
try {
119+
final oldDir = await _getOldDocumentDir();
120+
final newDir = await _getNewDocumentDir();
121+
122+
// List all analytics files in the old directory
123+
final oldDirFiles = oldDir.listSync()
124+
.whereType<File>()
125+
.where((file) => file.path.contains('analytics-flutter-') && file.path.endsWith('.json'))
126+
.toList();
127+
128+
for (final oldFile in oldDirFiles) {
129+
final fileName = oldFile.path.split('/').last;
130+
final newFilePath = '${newDir.path}/$fileName';
131+
final newFile = File(newFilePath);
132+
133+
// Only migrate if the file doesn't already exist in the new location
134+
if (!await newFile.exists()) {
135+
try {
136+
// Ensure the new directory exists
137+
await newDir.create(recursive: true);
138+
139+
// Copy the file to the new location
140+
await oldFile.copy(newFilePath);
141+
142+
// Delete the old file after successful copy
143+
await oldFile.delete();
144+
} catch (e) {
145+
// The app should continue to work even if migration fails
146+
}
147+
}
148+
}
149+
} catch (e) {
150+
// Migration failure shouldn't break the app
151+
}
152+
}
153+
99154
@override
100155
void dispose() {}
101156
}

0 commit comments

Comments
 (0)