diff --git a/mobile/lib/providers/asset.provider.dart b/mobile/lib/providers/asset.provider.dart index a0a3879db5..13b4ad4084 100644 --- a/mobile/lib/providers/asset.provider.dart +++ b/mobile/lib/providers/asset.provider.dart @@ -50,8 +50,19 @@ class AssetNotifier extends StateNotifier { await clearAssetsAndAlbums(_db); log.info("Manual refresh requested, cleared assets and albums from db"); } + final bool changedUsers = await _userService.refreshUsers(); + + final assetCount = await _db.assets.count(); + + if (assetCount == 0) { + debugPrint("First sync, refreshing all assets"); + await _assetService.refreshRemoteAssets(firstSync: true); + debugPrint("First sync, DONE refreshing all assets"); + } + debugPrint("First sync, CONTINUE refreshing all assets"); final bool newRemote = await _assetService.refreshRemoteAssets(); + final bool newLocal = await _albumService.refreshDeviceAlbums(); debugPrint( "changedUsers: $changedUsers, newRemote: $newRemote, newLocal: $newLocal", diff --git a/mobile/lib/services/asset.service.dart b/mobile/lib/services/asset.service.dart index 5751c00b47..de38ac200e 100644 --- a/mobile/lib/services/asset.service.dart +++ b/mobile/lib/services/asset.service.dart @@ -43,7 +43,7 @@ class AssetService { /// Checks the server for updated assets and updates the local database if /// required. Returns `true` if there were any changes. - Future refreshRemoteAssets() async { + Future refreshRemoteAssets({bool firstSync = false}) async { final syncedUserIds = await _db.eTags.where().idProperty().findAll(); final List syncedUsers = syncedUserIds.isEmpty ? [] @@ -57,6 +57,7 @@ class AssetService { getChangedAssets: _getRemoteAssetChanges, loadAssets: _getRemoteAssets, refreshUsers: _userService.getUsersFromServer, + firstSync: firstSync, ); debugPrint("refreshRemoteAssets full took ${sw.elapsedMilliseconds}ms"); return changes; @@ -97,8 +98,12 @@ class AssetService { } /// Returns `null` if the server state did not change, else list of assets - Future?> _getRemoteAssets(User user, DateTime until) async { - const int chunkSize = 10000; + Future?> _getRemoteAssets( + User user, + DateTime until, + bool firstSync, + ) async { + int chunkSize = firstSync ? 1000 : 10000; try { final List allAssets = []; String? lastId; @@ -120,6 +125,11 @@ class AssetService { allAssets.addAll(assets.map(Asset.remote)); if (assets.length != chunkSize) break; lastId = assets.last.id; + + if (firstSync) { + // first sync only loads the first chunk + break; + } } return allAssets; } catch (error, stack) { diff --git a/mobile/lib/services/sync.service.dart b/mobile/lib/services/sync.service.dart index 8ec56e925f..326d626ad8 100644 --- a/mobile/lib/services/sync.service.dart +++ b/mobile/lib/services/sync.service.dart @@ -46,14 +46,18 @@ class SyncService { List users, DateTime since, ) getChangedAssets, - required FutureOr?> Function(User user, DateTime until) - loadAssets, + required FutureOr?> Function( + User user, + DateTime until, + bool firstSync, + ) loadAssets, required FutureOr?> Function() refreshUsers, + required bool firstSync, }) => _lock.run( () async => await _syncRemoteAssetChanges(users, getChangedAssets) ?? - await _syncRemoteAssetsFull(refreshUsers, loadAssets), + await _syncRemoteAssetsFull(refreshUsers, loadAssets, firstSync), ); /// Syncs remote albums to the database @@ -212,7 +216,9 @@ class SyncService { /// Syncs assets by loading and comparing all assets from the server. Future _syncRemoteAssetsFull( FutureOr?> Function() refreshUsers, - FutureOr?> Function(User user, DateTime until) loadAssets, + FutureOr?> Function(User user, DateTime until, bool firstSync) + loadAssets, + bool firstSync, ) async { final serverUsers = await refreshUsers(); if (serverUsers == null) { @@ -228,17 +234,19 @@ class SyncService { .findAll(); bool changes = false; for (User u in users) { - changes |= await _syncRemoteAssetsForUser(u, loadAssets); + changes |= await _syncRemoteAssetsForUser(u, loadAssets, firstSync); } return changes; } Future _syncRemoteAssetsForUser( User user, - FutureOr?> Function(User user, DateTime until) loadAssets, + FutureOr?> Function(User user, DateTime until, bool firstSync) + loadAssets, + bool firstSync, ) async { final DateTime now = DateTime.now().toUtc(); - final List? remote = await loadAssets(user, now); + final List? remote = await loadAssets(user, now, firstSync); if (remote == null) { return false; } diff --git a/mobile/test/modules/shared/sync_service_test.dart b/mobile/test/modules/shared/sync_service_test.dart index 24f0c443ba..a910e17e82 100644 --- a/mobile/test/modules/shared/sync_service_test.dart +++ b/mobile/test/modules/shared/sync_service_test.dart @@ -78,8 +78,9 @@ void main() { final bool c1 = await s.syncRemoteAssetsToDb( users: [owner], getChangedAssets: _failDiff, - loadAssets: (u, d) => remoteAssets, + loadAssets: (u, d, firstSync) => remoteAssets, refreshUsers: () => [owner], + firstSync: false, ); expect(c1, isFalse); expect(db.assets.countSync(), 5); @@ -99,8 +100,9 @@ void main() { final bool c1 = await s.syncRemoteAssetsToDb( users: [owner], getChangedAssets: _failDiff, - loadAssets: (u, d) => remoteAssets, + loadAssets: (u, d, firstSync) => remoteAssets, refreshUsers: () => [owner], + firstSync: false, ); expect(c1, isTrue); expect(db.assets.countSync(), 7); @@ -120,16 +122,18 @@ void main() { final bool c1 = await s.syncRemoteAssetsToDb( users: [owner], getChangedAssets: _failDiff, - loadAssets: (u, d) => remoteAssets, + loadAssets: (u, d, firstSync) => remoteAssets, refreshUsers: () => [owner], + firstSync: false, ); expect(c1, isTrue); expect(db.assets.countSync(), 8); final bool c2 = await s.syncRemoteAssetsToDb( users: [owner], getChangedAssets: _failDiff, - loadAssets: (u, d) => remoteAssets, + loadAssets: (u, d, firstSync) => remoteAssets, refreshUsers: () => [owner], + firstSync: false, ); expect(c2, isFalse); expect(db.assets.countSync(), 8); @@ -137,8 +141,9 @@ void main() { final bool c3 = await s.syncRemoteAssetsToDb( users: [owner], getChangedAssets: _failDiff, - loadAssets: (u, d) => remoteAssets, + loadAssets: (u, d, firstSync) => remoteAssets, refreshUsers: () => [owner], + firstSync: false, ); expect(c3, isTrue); expect(db.assets.countSync(), 7); @@ -147,8 +152,9 @@ void main() { final bool c4 = await s.syncRemoteAssetsToDb( users: [owner], getChangedAssets: _failDiff, - loadAssets: (u, d) => remoteAssets, + loadAssets: (u, d, firstSync) => remoteAssets, refreshUsers: () => [owner], + firstSync: false, ); expect(c4, isTrue); expect(db.assets.countSync(), 9); @@ -166,8 +172,9 @@ void main() { final bool c = await s.syncRemoteAssetsToDb( users: [owner], getChangedAssets: (user, since) async => (toUpsert, toDelete), - loadAssets: (user, date) => throw Exception(), + loadAssets: (user, date, firstSync) => throw Exception(), refreshUsers: () => throw Exception(), + firstSync: false, ); expect(c, isTrue); expect(db.assets.countSync(), 6);