Skip to content

Commit

Permalink
Merge pull request #659 from hpi-studyu/fix/outdated-cached-subject
Browse files Browse the repository at this point in the history
Fix/outdated cached subject
  • Loading branch information
johannesvedder committed Jul 24, 2024
2 parents 1fa819c + 3a57727 commit 2dc126f
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 6 deletions.
2 changes: 2 additions & 0 deletions app/lib/screens/app_onboarding/loading_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ class _LoadingScreenState extends State<LoadingScreen> {
subject = await _fetchRemoteSubject(selectedStudyObjectId);
}
} catch (exception) {
debugPrint(
"Could not login and retrieve the study subject: $exception");
if (exception is SocketException) {
subject = await Cache.loadSubject();
StudyULogger.info("Offline mode with cached subject: $subject");
Expand Down
36 changes: 30 additions & 6 deletions app/lib/util/cache.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,37 @@ class Cache {
assert(subject == (await loadSubject()));
}

static Future<StudySubject> loadSubject() async {
static Future<StudySubject> loadSubject({StudySubject? backupSubject}) async {
// debugPrint("Load subject from cache");
if (await SecureStorage.containsKey(cacheSubjectKey)) {
return StudySubject.fromJson(
jsonDecode((await SecureStorage.read(cacheSubjectKey))!)
as Map<String, dynamic>,
);
final cachedSubjectStr = await SecureStorage.read(cacheSubjectKey);
final cachedSubject =
jsonDecode(cachedSubjectStr!) as Map<String, dynamic>;
try {
return StudySubject.fromJson(cachedSubject);
} catch (e) {
StudyULogger.warning(
"Failed to parse cached subject: $cachedSubjectStr",
);
if (backupSubject != null) {
// Only take progress from cached subject and rest from backup,
// as the cached subject might be outdated or corrupted

// compare IDs to make sure we are not mixing up subjects
// If IDs do not match we should not use the cached subject
if (backupSubject.id != cachedSubject['id']) {
throw Exception(
"Cached subject ID does not match remote subject ID",
);
}
final cachedProgress = (cachedSubject['progress'] as List?)
?.map((e) => SubjectProgress.fromJson(e as Map<String, dynamic>))
.toList();
backupSubject.progress = cachedProgress ?? backupSubject.progress;
return backupSubject;
}
throw Exception("No backup subject provided");
}
} else {
throw Exception("No cached subject found");
}
Expand Down Expand Up @@ -69,7 +93,7 @@ class Cache {
if (!(await SecureStorage.containsKey(cacheSubjectKey))) {
return remoteSubject;
}
final localSubject = await loadSubject();
final localSubject = await loadSubject(backupSubject: remoteSubject);
// local and remote subject are equal, nothing to synchronize
if (localSubject == remoteSubject) return remoteSubject;
// remote subject belongs to a different study
Expand Down

0 comments on commit 2dc126f

Please sign in to comment.