diff --git a/mobile/lib/domain/services/user.service.dart b/mobile/lib/domain/services/user.service.dart
index 48a6f5777d..a7eac71291 100644
--- a/mobile/lib/domain/services/user.service.dart
+++ b/mobile/lib/domain/services/user.service.dart
@@ -44,10 +44,14 @@ class UserService {
 
   Future<String?> createProfileImage(String name, Uint8List image) async {
     try {
-      return await _userApiRepository.createProfileImage(
+      final path = await _userApiRepository.createProfileImage(
         name: name,
         data: image,
       );
+      final updatedUser = getMyUser().copyWith(profileImagePath: path);
+      await _storeService.put(StoreKey.currentUser, updatedUser);
+      await _userRepository.update(updatedUser);
+      return path;
     } catch (e) {
       _log.warning("Failed to upload profile image", e);
       return null;
diff --git a/mobile/lib/providers/auth.provider.dart b/mobile/lib/providers/auth.provider.dart
index 2a140911b0..9187808984 100644
--- a/mobile/lib/providers/auth.provider.dart
+++ b/mobile/lib/providers/auth.provider.dart
@@ -3,11 +3,12 @@ import 'package:flutter_udid/flutter_udid.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
 import 'package:immich_mobile/domain/models/store.model.dart';
 import 'package:immich_mobile/domain/models/user.model.dart';
+import 'package:immich_mobile/domain/services/user.service.dart';
 import 'package:immich_mobile/entities/store.entity.dart';
-import 'package:immich_mobile/infrastructure/utils/user.converter.dart';
 import 'package:immich_mobile/models/auth/auth_state.model.dart';
 import 'package:immich_mobile/models/auth/login_response.model.dart';
 import 'package:immich_mobile/providers/api.provider.dart';
+import 'package:immich_mobile/providers/infrastructure/user.provider.dart';
 import 'package:immich_mobile/services/api.service.dart';
 import 'package:immich_mobile/services/auth.service.dart';
 import 'package:immich_mobile/utils/hash.dart';
@@ -18,20 +19,20 @@ final authProvider = StateNotifierProvider<AuthNotifier, AuthState>((ref) {
   return AuthNotifier(
     ref.watch(authServiceProvider),
     ref.watch(apiServiceProvider),
+    ref.watch(userServiceProvider),
   );
 });
 
 class AuthNotifier extends StateNotifier<AuthState> {
   final AuthService _authService;
   final ApiService _apiService;
+  final UserService _userService;
   final _log = Logger("AuthenticationNotifier");
 
   static const Duration _timeoutDuration = Duration(seconds: 7);
 
-  AuthNotifier(
-    this._authService,
-    this._apiService,
-  ) : super(
+  AuthNotifier(this._authService, this._apiService, this._userService)
+      : super(
           AuthState(
             deviceId: "",
             userId: "",
@@ -106,17 +107,21 @@ class AuthNotifier extends StateNotifier<AuthState> {
     String deviceId =
         Store.tryGet(StoreKey.deviceId) ?? await FlutterUdid.consistentUdid;
 
-    UserDto? user = Store.tryGet(StoreKey.currentUser);
+    UserDto? user = _userService.tryGetMyUser();
 
-    UserAdminResponseDto? userResponse;
-    UserPreferencesResponseDto? userPreferences;
     try {
-      final responses = await Future.wait([
-        _apiService.usersApi.getMyUser().timeout(_timeoutDuration),
-        _apiService.usersApi.getMyPreferences().timeout(_timeoutDuration),
-      ]);
-      userResponse = responses[0] as UserAdminResponseDto;
-      userPreferences = responses[1] as UserPreferencesResponseDto;
+      final serverUser =
+          await _userService.refreshMyUser().timeout(_timeoutDuration);
+      if (serverUser == null) {
+        _log.severe("Unable to get user information from the server.");
+      } else {
+        // If the user information is successfully retrieved, update the store
+        // Due to the flow of the code, this will always happen on first login
+        user = serverUser;
+        await Store.put(StoreKey.deviceId, deviceId);
+        await Store.put(StoreKey.deviceIdHash, fastHash(deviceId));
+        await Store.put(StoreKey.accessToken, accessToken);
+      }
     } on ApiException catch (error, stackTrace) {
       if (error.code == 401) {
         _log.severe("Unauthorized access, token likely expired. Logging out.");
@@ -140,22 +145,6 @@ class AuthNotifier extends StateNotifier<AuthState> {
       }
     }
 
-    // If the user information is successfully retrieved, update the store
-    // Due to the flow of the code, this will always happen on first login
-    if (userResponse == null) {
-      _log.severe("Unable to get user information from the server.");
-    } else {
-      await Store.put(StoreKey.deviceId, deviceId);
-      await Store.put(StoreKey.deviceIdHash, fastHash(deviceId));
-      await Store.put(
-        StoreKey.currentUser,
-        UserConverter.fromAdminDto(userResponse, userPreferences),
-      );
-      await Store.put(StoreKey.accessToken, accessToken);
-
-      user = UserConverter.fromAdminDto(userResponse, userPreferences);
-    }
-
     // If the user is null, the login was not successful
     // and we don't have a local copy of the user from a prior successful login
     if (user == null) {
@@ -163,13 +152,13 @@ class AuthNotifier extends StateNotifier<AuthState> {
     }
 
     state = state.copyWith(
-      isAuthenticated: true,
+      deviceId: deviceId,
       userId: user.uid,
       userEmail: user.email,
+      isAuthenticated: true,
       name: user.name,
-      profileImagePath: user.profileImagePath,
       isAdmin: user.isAdmin,
-      deviceId: deviceId,
+      profileImagePath: user.profileImagePath,
     );
 
     return true;
diff --git a/mobile/lib/providers/user.provider.dart b/mobile/lib/providers/user.provider.dart
index fb574fa99a..c3623106e8 100644
--- a/mobile/lib/providers/user.provider.dart
+++ b/mobile/lib/providers/user.provider.dart
@@ -1,34 +1,24 @@
 import 'dart:async';
 
 import 'package:hooks_riverpod/hooks_riverpod.dart';
-import 'package:immich_mobile/domain/models/store.model.dart';
 import 'package:immich_mobile/domain/models/user.model.dart';
-import 'package:immich_mobile/entities/store.entity.dart';
-import 'package:immich_mobile/infrastructure/utils/user.converter.dart';
-import 'package:immich_mobile/providers/api.provider.dart';
-import 'package:immich_mobile/services/api.service.dart';
+import 'package:immich_mobile/domain/services/user.service.dart';
+import 'package:immich_mobile/providers/infrastructure/user.provider.dart';
 import 'package:immich_mobile/services/timeline.service.dart';
 
 class CurrentUserProvider extends StateNotifier<UserDto?> {
-  CurrentUserProvider(this._apiService) : super(null) {
-    state = Store.tryGet(StoreKey.currentUser);
+  CurrentUserProvider(this._userService) : super(null) {
+    state = _userService.tryGetMyUser();
     streamSub =
-        Store.watch(StoreKey.currentUser).listen((user) => state = user);
+        _userService.watchMyUser().listen((user) => state = user ?? state);
   }
 
-  final ApiService _apiService;
+  final UserService _userService;
   late final StreamSubscription<UserDto?> streamSub;
 
   refresh() async {
     try {
-      final user = await _apiService.usersApi.getMyUser();
-      final userPreferences = await _apiService.usersApi.getMyPreferences();
-      if (user != null) {
-        await Store.put(
-          StoreKey.currentUser,
-          UserConverter.fromAdminDto(user, userPreferences),
-        );
-      }
+      await _userService.refreshMyUser();
     } catch (_) {}
   }
 
@@ -41,9 +31,7 @@ class CurrentUserProvider extends StateNotifier<UserDto?> {
 
 final currentUserProvider =
     StateNotifierProvider<CurrentUserProvider, UserDto?>((ref) {
-  return CurrentUserProvider(
-    ref.watch(apiServiceProvider),
-  );
+  return CurrentUserProvider(ref.watch(userServiceProvider));
 });
 
 class TimelineUserIdsProvider extends StateNotifier<List<int>> {
diff --git a/mobile/lib/routing/tab_navigation_observer.dart b/mobile/lib/routing/tab_navigation_observer.dart
index edbfe6da4c..d95820885e 100644
--- a/mobile/lib/routing/tab_navigation_observer.dart
+++ b/mobile/lib/routing/tab_navigation_observer.dart
@@ -1,11 +1,8 @@
 import 'package:auto_route/auto_route.dart';
 import 'package:flutter/foundation.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
-import 'package:immich_mobile/domain/models/store.model.dart';
-import 'package:immich_mobile/entities/store.entity.dart';
-import 'package:immich_mobile/infrastructure/utils/user.converter.dart';
-import 'package:immich_mobile/providers/api.provider.dart';
 import 'package:immich_mobile/providers/asset.provider.dart';
+import 'package:immich_mobile/providers/infrastructure/user.provider.dart';
 import 'package:immich_mobile/providers/memory.provider.dart';
 import 'package:immich_mobile/providers/server_info.provider.dart';
 
@@ -28,19 +25,7 @@ class TabNavigationObserver extends AutoRouterObserver {
 
       // Update user info
       try {
-        final userResponseDto =
-            await ref.read(apiServiceProvider).usersApi.getMyUser();
-        final userPreferences =
-            await ref.read(apiServiceProvider).usersApi.getMyPreferences();
-
-        if (userResponseDto == null) {
-          return;
-        }
-
-        await Store.put(
-          StoreKey.currentUser,
-          UserConverter.fromAdminDto(userResponseDto, userPreferences),
-        );
+        ref.read(userServiceProvider).refreshMyUser();
         ref.read(serverInfoProvider.notifier).getServerVersion();
       } catch (e) {
         debugPrint("Error refreshing user info $e");
diff --git a/mobile/lib/services/album.service.dart b/mobile/lib/services/album.service.dart
index d3fe7674d5..1251ef51fe 100644
--- a/mobile/lib/services/album.service.dart
+++ b/mobile/lib/services/album.service.dart
@@ -6,12 +6,11 @@ import 'package:collection/collection.dart';
 import 'package:flutter/foundation.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
 import 'package:immich_mobile/constants/enums.dart';
-import 'package:immich_mobile/domain/models/store.model.dart';
 import 'package:immich_mobile/domain/models/user.model.dart';
+import 'package:immich_mobile/domain/services/user.service.dart';
 import 'package:immich_mobile/entities/album.entity.dart';
 import 'package:immich_mobile/entities/asset.entity.dart';
 import 'package:immich_mobile/entities/backup_album.entity.dart';
-import 'package:immich_mobile/entities/store.entity.dart';
 import 'package:immich_mobile/infrastructure/entities/user.entity.dart'
     as entity;
 import 'package:immich_mobile/interfaces/album.interface.dart';
@@ -21,6 +20,7 @@ import 'package:immich_mobile/interfaces/asset.interface.dart';
 import 'package:immich_mobile/interfaces/backup_album.interface.dart';
 import 'package:immich_mobile/models/albums/album_add_asset_response.model.dart';
 import 'package:immich_mobile/models/albums/album_search.model.dart';
+import 'package:immich_mobile/providers/infrastructure/user.provider.dart';
 import 'package:immich_mobile/repositories/album.repository.dart';
 import 'package:immich_mobile/repositories/album_api.repository.dart';
 import 'package:immich_mobile/repositories/album_media.repository.dart';
@@ -33,6 +33,7 @@ import 'package:logging/logging.dart';
 final albumServiceProvider = Provider(
   (ref) => AlbumService(
     ref.watch(syncServiceProvider),
+    ref.watch(userServiceProvider),
     ref.watch(entityServiceProvider),
     ref.watch(albumRepositoryProvider),
     ref.watch(assetRepositoryProvider),
@@ -44,6 +45,7 @@ final albumServiceProvider = Provider(
 
 class AlbumService {
   final SyncService _syncService;
+  final UserService _userService;
   final EntityService _entityService;
   final IAlbumRepository _albumRepository;
   final IAssetRepository _assetRepository;
@@ -56,6 +58,7 @@ class AlbumService {
 
   AlbumService(
     this._syncService,
+    this._userService,
     this._entityService,
     this._albumRepository,
     this._assetRepository,
@@ -292,7 +295,7 @@ class AlbumService {
 
   Future<bool> deleteAlbum(Album album) async {
     try {
-      final userId = Store.get(StoreKey.currentUser).id;
+      final userId = _userService.getMyUser().id;
       if (album.owner.value?.isarId == userId) {
         await _albumApiRepository.delete(album.remoteId!);
       }
diff --git a/mobile/lib/services/api.service.dart b/mobile/lib/services/api.service.dart
index 0ef68e1c41..1d17b71211 100644
--- a/mobile/lib/services/api.service.dart
+++ b/mobile/lib/services/api.service.dart
@@ -35,6 +35,9 @@ class ApiService implements Authentication {
   late MemoriesApi memoriesApi;
 
   ApiService() {
+    // The below line ensures that the api clients are initialized when the service is instantiated
+    // This is required to avoid late initialization errors when the clients are access before the endpoint is resolved
+    setEndpoint('');
     final endpoint = Store.tryGet(StoreKey.serverEndpoint);
     if (endpoint != null && endpoint.isNotEmpty) {
       setEndpoint(endpoint);
diff --git a/mobile/lib/services/asset.service.dart b/mobile/lib/services/asset.service.dart
index ff3e908ac3..6eff80ae02 100644
--- a/mobile/lib/services/asset.service.dart
+++ b/mobile/lib/services/asset.service.dart
@@ -6,9 +6,8 @@ import 'package:flutter/material.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
 import 'package:immich_mobile/domain/interfaces/exif.interface.dart';
 import 'package:immich_mobile/domain/interfaces/user.interface.dart';
-import 'package:immich_mobile/domain/models/store.model.dart';
 import 'package:immich_mobile/domain/models/user.model.dart';
-import 'package:immich_mobile/domain/services/store.service.dart';
+import 'package:immich_mobile/domain/services/user.service.dart';
 import 'package:immich_mobile/entities/asset.entity.dart';
 import 'package:immich_mobile/entities/backup_album.entity.dart';
 import 'package:immich_mobile/interfaces/asset.interface.dart';
@@ -19,9 +18,7 @@ import 'package:immich_mobile/interfaces/etag.interface.dart';
 import 'package:immich_mobile/models/backup/backup_candidate.model.dart';
 import 'package:immich_mobile/providers/api.provider.dart';
 import 'package:immich_mobile/providers/infrastructure/exif.provider.dart';
-import 'package:immich_mobile/providers/infrastructure/store.provider.dart';
-import 'package:immich_mobile/providers/infrastructure/user.provider.dart'
-    hide userServiceProvider;
+import 'package:immich_mobile/providers/infrastructure/user.provider.dart';
 import 'package:immich_mobile/repositories/asset.repository.dart';
 import 'package:immich_mobile/repositories/asset_api.repository.dart';
 import 'package:immich_mobile/repositories/asset_media.repository.dart';
@@ -47,7 +44,7 @@ final assetServiceProvider = Provider(
     ref.watch(syncServiceProvider),
     ref.watch(backupServiceProvider),
     ref.watch(albumServiceProvider),
-    ref.watch(storeServiceProvider),
+    ref.watch(userServiceProvider),
     ref.watch(assetMediaRepositoryProvider),
   ),
 );
@@ -63,7 +60,7 @@ class AssetService {
   final SyncService _syncService;
   final BackupService _backupService;
   final AlbumService _albumService;
-  final StoreService _storeService;
+  final UserService _userService;
   final IAssetMediaRepository _assetMediaRepository;
   final log = Logger('AssetService');
 
@@ -78,7 +75,7 @@ class AssetService {
     this._syncService,
     this._backupService,
     this._albumService,
-    this._storeService,
+    this._userService,
     this._assetMediaRepository,
   );
 
@@ -316,7 +313,7 @@ class AssetService {
       );
 
       await refreshRemoteAssets();
-      final owner = _storeService.get(StoreKey.currentUser);
+      final owner = _userService.getMyUser();
       final remoteAssets = await _assetRepository.getAll(
         ownerId: owner.id,
         state: AssetState.merged,
@@ -522,12 +519,12 @@ class AssetService {
   }
 
   Future<List<Asset>> getRecentlyAddedAssets() {
-    final me = _storeService.get(StoreKey.currentUser);
+    final me = _userService.getMyUser();
     return _assetRepository.getRecentlyAddedAssets(me.id);
   }
 
   Future<List<Asset>> getMotionAssets() {
-    final me = _storeService.get(StoreKey.currentUser);
+    final me = _userService.getMyUser();
     return _assetRepository.getMotionAssets(me.id);
   }
 }
diff --git a/mobile/lib/services/backup_verification.service.dart b/mobile/lib/services/backup_verification.service.dart
index e4d5ab4afd..9aa021a324 100644
--- a/mobile/lib/services/backup_verification.service.dart
+++ b/mobile/lib/services/backup_verification.service.dart
@@ -8,12 +8,14 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
 import 'package:immich_mobile/domain/interfaces/exif.interface.dart';
 import 'package:immich_mobile/domain/models/exif.model.dart';
 import 'package:immich_mobile/domain/models/store.model.dart';
+import 'package:immich_mobile/domain/services/user.service.dart';
 import 'package:immich_mobile/entities/asset.entity.dart';
 import 'package:immich_mobile/entities/store.entity.dart';
 import 'package:immich_mobile/infrastructure/utils/exif.converter.dart';
 import 'package:immich_mobile/interfaces/asset.interface.dart';
 import 'package:immich_mobile/interfaces/file_media.interface.dart';
 import 'package:immich_mobile/providers/infrastructure/exif.provider.dart';
+import 'package:immich_mobile/providers/infrastructure/user.provider.dart';
 import 'package:immich_mobile/repositories/asset.repository.dart';
 import 'package:immich_mobile/repositories/file_media.repository.dart';
 import 'package:immich_mobile/services/api.service.dart';
@@ -22,11 +24,13 @@ import 'package:immich_mobile/utils/diff.dart';
 
 /// Finds duplicates originating from missing EXIF information
 class BackupVerificationService {
+  final UserService _userService;
   final IFileMediaRepository _fileMediaRepository;
   final IAssetRepository _assetRepository;
   final IExifInfoRepository _exifInfoRepository;
 
-  BackupVerificationService(
+  const BackupVerificationService(
+    this._userService,
     this._fileMediaRepository,
     this._assetRepository,
     this._exifInfoRepository,
@@ -34,7 +38,7 @@ class BackupVerificationService {
 
   /// Returns at most [limit] assets that were backed up without exif
   Future<List<Asset>> findWronglyBackedUpAssets({int limit = 100}) async {
-    final owner = Store.get(StoreKey.currentUser).id;
+    final owner = _userService.getMyUser().id;
     final List<Asset> onlyLocal = await _assetRepository.getAll(
       ownerId: owner,
       state: AssetState.local,
@@ -214,6 +218,7 @@ class BackupVerificationService {
 
 final backupVerificationServiceProvider = Provider(
   (ref) => BackupVerificationService(
+    ref.watch(userServiceProvider),
     ref.watch(fileMediaRepositoryProvider),
     ref.watch(assetRepositoryProvider),
     ref.watch(exifRepositoryProvider),
diff --git a/mobile/lib/services/sync.service.dart b/mobile/lib/services/sync.service.dart
index a598941f81..24f2fd00d6 100644
--- a/mobile/lib/services/sync.service.dart
+++ b/mobile/lib/services/sync.service.dart
@@ -5,9 +5,8 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
 import 'package:immich_mobile/domain/interfaces/exif.interface.dart';
 import 'package:immich_mobile/domain/interfaces/user.interface.dart';
 import 'package:immich_mobile/domain/interfaces/user_api.repository.dart';
-import 'package:immich_mobile/domain/models/store.model.dart';
 import 'package:immich_mobile/domain/models/user.model.dart';
-import 'package:immich_mobile/domain/services/store.service.dart';
+import 'package:immich_mobile/domain/services/user.service.dart';
 import 'package:immich_mobile/entities/album.entity.dart';
 import 'package:immich_mobile/entities/asset.entity.dart';
 import 'package:immich_mobile/entities/etag.entity.dart';
@@ -20,7 +19,6 @@ import 'package:immich_mobile/interfaces/etag.interface.dart';
 import 'package:immich_mobile/interfaces/partner.interface.dart';
 import 'package:immich_mobile/interfaces/partner_api.interface.dart';
 import 'package:immich_mobile/providers/infrastructure/exif.provider.dart';
-import 'package:immich_mobile/providers/infrastructure/store.provider.dart';
 import 'package:immich_mobile/providers/infrastructure/user.provider.dart';
 import 'package:immich_mobile/repositories/album.repository.dart';
 import 'package:immich_mobile/repositories/album_api.repository.dart';
@@ -47,7 +45,7 @@ final syncServiceProvider = Provider(
     ref.watch(exifRepositoryProvider),
     ref.watch(partnerRepositoryProvider),
     ref.watch(userRepositoryProvider),
-    ref.watch(storeServiceProvider),
+    ref.watch(userServiceProvider),
     ref.watch(etagRepositoryProvider),
     ref.watch(partnerApiRepositoryProvider),
     ref.watch(userApiRepositoryProvider),
@@ -63,8 +61,8 @@ class SyncService {
   final IAssetRepository _assetRepository;
   final IExifInfoRepository _exifInfoRepository;
   final IUserRepository _userRepository;
+  final UserService _userService;
   final IPartnerRepository _partnerRepository;
-  final StoreService _storeService;
   final IETagRepository _eTagRepository;
   final IPartnerApiRepository _partnerApiRepository;
   final IUserApiRepository _userApiRepository;
@@ -81,7 +79,7 @@ class SyncService {
     this._exifInfoRepository,
     this._partnerRepository,
     this._userRepository,
-    this._storeService,
+    this._userService,
     this._eTagRepository,
     this._partnerApiRepository,
     this._userApiRepository,
@@ -210,7 +208,7 @@ class SyncService {
       DateTime since,
     ) getChangedAssets,
   ) async {
-    final currentUser = _storeService.get(StoreKey.currentUser);
+    final currentUser = _userService.getMyUser();
     final DateTime? since =
         (await _eTagRepository.get(currentUser.id))?.time?.toUtc();
     if (since == null) return null;
@@ -261,7 +259,7 @@ class SyncService {
 
   Future<List<UserDto>> _getAllAccessibleUsers() async {
     final sharedWith = (await _partnerRepository.getSharedWith()).toSet();
-    sharedWith.add(_storeService.get(StoreKey.currentUser));
+    sharedWith.add(_userService.getMyUser());
     return sharedWith.toList();
   }
 
@@ -455,7 +453,7 @@ class SyncService {
     }
 
     if (album.shared || dto.shared) {
-      final userId = (_storeService.get(StoreKey.currentUser)).id;
+      final userId = (_userService.getMyUser()).id;
       final foreign =
           await _assetRepository.getByAlbum(album, notOwnedBy: [userId]);
       existing.addAll(foreign);
@@ -591,7 +589,7 @@ class SyncService {
     // general case, e.g. some assets have been deleted or there are excluded albums on iOS
     final inDb = await _assetRepository.getByAlbum(
       dbAlbum,
-      ownerId: (_storeService.get(StoreKey.currentUser)).id,
+      ownerId: (_userService.getMyUser()).id,
       sortBy: AssetSort.checksum,
     );
 
diff --git a/mobile/lib/services/timeline.service.dart b/mobile/lib/services/timeline.service.dart
index 03042e266b..dd2252602d 100644
--- a/mobile/lib/services/timeline.service.dart
+++ b/mobile/lib/services/timeline.service.dart
@@ -1,11 +1,10 @@
 import 'package:hooks_riverpod/hooks_riverpod.dart';
-import 'package:immich_mobile/domain/models/store.model.dart';
-import 'package:immich_mobile/domain/services/store.service.dart';
+import 'package:immich_mobile/domain/services/user.service.dart';
 import 'package:immich_mobile/entities/album.entity.dart';
 import 'package:immich_mobile/entities/asset.entity.dart';
 import 'package:immich_mobile/interfaces/timeline.interface.dart';
 import 'package:immich_mobile/providers/app_settings.provider.dart';
-import 'package:immich_mobile/providers/infrastructure/store.provider.dart';
+import 'package:immich_mobile/providers/infrastructure/user.provider.dart';
 import 'package:immich_mobile/repositories/timeline.repository.dart';
 import 'package:immich_mobile/services/app_settings.service.dart';
 import 'package:immich_mobile/widgets/asset_grid/asset_grid_data_structure.dart';
@@ -14,28 +13,28 @@ final timelineServiceProvider = Provider<TimelineService>((ref) {
   return TimelineService(
     ref.watch(timelineRepositoryProvider),
     ref.watch(appSettingsServiceProvider),
-    ref.watch(storeServiceProvider),
+    ref.watch(userServiceProvider),
   );
 });
 
 class TimelineService {
   final ITimelineRepository _timelineRepository;
   final AppSettingsService _appSettingsService;
-  final StoreService _storeService;
+  final UserService _userService;
 
   const TimelineService(
     this._timelineRepository,
     this._appSettingsService,
-    this._storeService,
+    this._userService,
   );
 
   Future<List<int>> getTimelineUserIds() async {
-    final me = _storeService.get(StoreKey.currentUser);
+    final me = _userService.getMyUser();
     return _timelineRepository.getTimelineUserIds(me.id);
   }
 
   Stream<List<int>> watchTimelineUserIds() async* {
-    final me = _storeService.get(StoreKey.currentUser);
+    final me = _userService.getMyUser();
     yield* _timelineRepository.watchTimelineUsers(me.id);
   }
 
@@ -51,13 +50,13 @@ class TimelineService {
   }
 
   Stream<RenderList> watchArchiveTimeline() async* {
-    final user = _storeService.get(StoreKey.currentUser);
+    final user = _userService.getMyUser();
 
     yield* _timelineRepository.watchArchiveTimeline(user.id);
   }
 
   Stream<RenderList> watchFavoriteTimeline() async* {
-    final user = _storeService.get(StoreKey.currentUser);
+    final user = _userService.getMyUser();
 
     yield* _timelineRepository.watchFavoriteTimeline(user.id);
   }
@@ -70,7 +69,7 @@ class TimelineService {
   }
 
   Stream<RenderList> watchTrashTimeline() async* {
-    final user = _storeService.get(StoreKey.currentUser);
+    final user = _userService.getMyUser();
 
     yield* _timelineRepository.watchTrashTimeline(user.id);
   }
@@ -97,7 +96,7 @@ class TimelineService {
   }
 
   Stream<RenderList> watchAssetSelectionTimeline() async* {
-    final user = _storeService.get(StoreKey.currentUser);
+    final user = _userService.getMyUser();
 
     yield* _timelineRepository.watchAssetSelectionTimeline(user.id);
   }
diff --git a/mobile/lib/services/trash.service.dart b/mobile/lib/services/trash.service.dart
index 338f063fd3..478ad65db0 100644
--- a/mobile/lib/services/trash.service.dart
+++ b/mobile/lib/services/trash.service.dart
@@ -1,10 +1,9 @@
 import 'package:hooks_riverpod/hooks_riverpod.dart';
-import 'package:immich_mobile/domain/models/store.model.dart';
-import 'package:immich_mobile/domain/services/store.service.dart';
+import 'package:immich_mobile/domain/services/user.service.dart';
 import 'package:immich_mobile/entities/asset.entity.dart';
 import 'package:immich_mobile/interfaces/asset.interface.dart';
 import 'package:immich_mobile/providers/api.provider.dart';
-import 'package:immich_mobile/providers/infrastructure/store.provider.dart';
+import 'package:immich_mobile/providers/infrastructure/user.provider.dart';
 import 'package:immich_mobile/repositories/asset.repository.dart';
 import 'package:immich_mobile/services/api.service.dart';
 import 'package:openapi/api.dart';
@@ -13,19 +12,19 @@ final trashServiceProvider = Provider<TrashService>((ref) {
   return TrashService(
     ref.watch(apiServiceProvider),
     ref.watch(assetRepositoryProvider),
-    ref.watch(storeServiceProvider),
+    ref.watch(userServiceProvider),
   );
 });
 
 class TrashService {
   final ApiService _apiService;
   final IAssetRepository _assetRepository;
-  final StoreService _storeService;
+  final UserService _userService;
 
-  TrashService(
+  const TrashService(
     this._apiService,
     this._assetRepository,
-    this._storeService,
+    this._userService,
   );
 
   Future<void> restoreAssets(Iterable<Asset> assetList) async {
@@ -43,7 +42,7 @@ class TrashService {
   }
 
   Future<void> emptyTrash() async {
-    final user = _storeService.get(StoreKey.currentUser);
+    final user = _userService.getMyUser();
 
     await _apiService.trashApi.emptyTrash();
 
@@ -74,7 +73,7 @@ class TrashService {
   }
 
   Future<void> restoreTrash() async {
-    final user = _storeService.get(StoreKey.currentUser);
+    final user = _userService.getMyUser();
 
     await _apiService.trashApi.restoreTrash();
 
diff --git a/mobile/lib/widgets/album/album_thumbnail_card.dart b/mobile/lib/widgets/album/album_thumbnail_card.dart
index ec984d1017..089544a9f1 100644
--- a/mobile/lib/widgets/album/album_thumbnail_card.dart
+++ b/mobile/lib/widgets/album/album_thumbnail_card.dart
@@ -1,13 +1,13 @@
 import 'package:easy_localization/easy_localization.dart';
 import 'package:flutter/material.dart';
-import 'package:immich_mobile/domain/models/store.model.dart';
+import 'package:hooks_riverpod/hooks_riverpod.dart';
 import 'package:immich_mobile/entities/album.entity.dart';
-import 'package:immich_mobile/entities/store.entity.dart';
 import 'package:immich_mobile/extensions/build_context_extensions.dart';
 import 'package:immich_mobile/extensions/theme_extensions.dart';
+import 'package:immich_mobile/providers/user.provider.dart';
 import 'package:immich_mobile/widgets/common/immich_thumbnail.dart';
 
-class AlbumThumbnailCard extends StatelessWidget {
+class AlbumThumbnailCard extends ConsumerWidget {
   final Function()? onTap;
 
   /// Whether or not to show the owner of the album (or "Owned")
@@ -26,7 +26,7 @@ class AlbumThumbnailCard extends StatelessWidget {
   final Album album;
 
   @override
-  Widget build(BuildContext context) {
+  Widget build(BuildContext context, WidgetRef ref) {
     return LayoutBuilder(
       builder: (context, constraints) {
         var cardSize = constraints.maxWidth;
@@ -58,7 +58,7 @@ class AlbumThumbnailCard extends StatelessWidget {
           // Add the owner name to the subtitle
           String? owner;
           if (showOwner) {
-            if (album.ownerId == Store.get(StoreKey.currentUser).uid) {
+            if (album.ownerId == ref.read(currentUserProvider)?.uid) {
               owner = 'album_thumbnail_owned'.tr();
             } else if (album.ownerName != null) {
               owner = 'album_thumbnail_shared_by'.tr(args: [album.ownerName!]);
diff --git a/mobile/lib/widgets/common/app_bar_dialog/app_bar_profile_info.dart b/mobile/lib/widgets/common/app_bar_dialog/app_bar_profile_info.dart
index 4d4376b71d..93cdcd0e6f 100644
--- a/mobile/lib/widgets/common/app_bar_dialog/app_bar_profile_info.dart
+++ b/mobile/lib/widgets/common/app_bar_dialog/app_bar_profile_info.dart
@@ -1,8 +1,6 @@
 import 'package:flutter/material.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
 import 'package:image_picker/image_picker.dart';
-import 'package:immich_mobile/domain/models/store.model.dart';
-import 'package:immich_mobile/entities/store.entity.dart';
 import 'package:immich_mobile/extensions/build_context_extensions.dart';
 import 'package:immich_mobile/extensions/theme_extensions.dart';
 import 'package:immich_mobile/providers/auth.provider.dart';
@@ -21,7 +19,7 @@ class AppBarProfileInfoBox extends HookConsumerWidget {
     final authState = ref.watch(authProvider);
     final uploadProfileImageStatus =
         ref.watch(uploadProfileImageProvider).status;
-    final user = Store.tryGet(StoreKey.currentUser);
+    final user = ref.watch(currentUserProvider);
 
     buildUserProfileImage() {
       if (user == null) {
@@ -67,9 +65,6 @@ class AppBarProfileInfoBox extends HookConsumerWidget {
                 profileImagePath,
               );
           if (user != null) {
-            final updatedUser =
-                user.copyWith(profileImagePath: profileImagePath);
-            await Store.put(StoreKey.currentUser, updatedUser);
             ref.read(currentUserProvider.notifier).refresh();
           }
         }
diff --git a/mobile/lib/widgets/common/immich_app_bar.dart b/mobile/lib/widgets/common/immich_app_bar.dart
index 7c1e0c1c4e..c776f7aa53 100644
--- a/mobile/lib/widgets/common/immich_app_bar.dart
+++ b/mobile/lib/widgets/common/immich_app_bar.dart
@@ -3,14 +3,13 @@ import 'package:easy_localization/easy_localization.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
-import 'package:immich_mobile/domain/models/store.model.dart';
-import 'package:immich_mobile/entities/store.entity.dart';
 import 'package:immich_mobile/extensions/build_context_extensions.dart';
 import 'package:immich_mobile/models/backup/backup_state.model.dart';
 import 'package:immich_mobile/models/server_info/server_info.model.dart';
 import 'package:immich_mobile/providers/backup/backup.provider.dart';
 import 'package:immich_mobile/providers/immich_logo_provider.dart';
 import 'package:immich_mobile/providers/server_info.provider.dart';
+import 'package:immich_mobile/providers/user.provider.dart';
 import 'package:immich_mobile/routing/router.dart';
 import 'package:immich_mobile/widgets/common/app_bar_dialog/app_bar_dialog.dart';
 import 'package:immich_mobile/widgets/common/user_circle_avatar.dart';
@@ -30,7 +29,7 @@ class ImmichAppBar extends ConsumerWidget implements PreferredSizeWidget {
         backupState.backgroundBackup || backupState.autoBackup;
     final ServerInfo serverInfoState = ref.watch(serverInfoProvider);
     final immichLogo = ref.watch(immichLogoProvider);
-    final user = Store.tryGet(StoreKey.currentUser);
+    final user = ref.watch(currentUserProvider);
     final isDarkTheme = context.isDarkTheme;
     const widgetSize = 30.0;
 
diff --git a/mobile/test/domain/services/user_service_test.dart b/mobile/test/domain/services/user_service_test.dart
index 512f5cb4a2..52344cc9a7 100644
--- a/mobile/test/domain/services/user_service_test.dart
+++ b/mobile/test/domain/services/user_service_test.dart
@@ -27,12 +27,16 @@ void main() {
       userApiRepository: mockUserApiRepo,
       storeService: mockStoreService,
     );
+
+    registerFallbackValue(UserStub.admin);
+    when(() => mockStoreService.get(StoreKey.currentUser))
+        .thenReturn(UserStub.admin);
+    when(() => mockStoreService.tryGet(StoreKey.currentUser))
+        .thenReturn(UserStub.admin);
   });
 
   group('getMyUser', () {
     test('should return user from store', () {
-      when(() => mockStoreService.get(StoreKey.currentUser))
-          .thenReturn(UserStub.admin);
       final result = sut.getMyUser();
       expect(result, UserStub.admin);
     });
@@ -47,8 +51,6 @@ void main() {
 
   group('tryGetMyUser', () {
     test('should return user from store', () {
-      when(() => mockStoreService.tryGet(StoreKey.currentUser))
-          .thenReturn(UserStub.admin);
       final result = sut.tryGetMyUser();
       expect(result, UserStub.admin);
     });
@@ -107,26 +109,48 @@ void main() {
 
   group('createProfileImage', () {
     test('should return profile image path', () async {
+      const profileImagePath = 'profile.jpg';
+      final updatedUser =
+          UserStub.admin.copyWith(profileImagePath: profileImagePath);
+
       when(
         () => mockUserApiRepo.createProfileImage(
-          name: 'profile.jpg',
+          name: profileImagePath,
           data: Uint8List(0),
         ),
-      ).thenAnswer((_) async => 'profile.jpg');
+      ).thenAnswer((_) async => profileImagePath);
+      when(() => mockStoreService.put(StoreKey.currentUser, updatedUser))
+          .thenAnswer((_) async => true);
+      when(() => mockUserRepo.update(updatedUser))
+          .thenAnswer((_) async => UserStub.admin);
 
-      final result = await sut.createProfileImage('profile.jpg', Uint8List(0));
-      expect(result, 'profile.jpg');
+      final result =
+          await sut.createProfileImage(profileImagePath, Uint8List(0));
+
+      verify(() => mockStoreService.put(StoreKey.currentUser, updatedUser))
+          .called(1);
+      verify(() => mockUserRepo.update(updatedUser)).called(1);
+      expect(result, profileImagePath);
     });
 
     test('should return null if profile image creation fails', () async {
+      const profileImagePath = 'profile.jpg';
+      final updatedUser =
+          UserStub.admin.copyWith(profileImagePath: profileImagePath);
+
       when(
         () => mockUserApiRepo.createProfileImage(
-          name: 'profile.jpg',
+          name: profileImagePath,
           data: Uint8List(0),
         ),
       ).thenThrow(Exception('Failed to create profile image'));
 
-      final result = await sut.createProfileImage('profile.jpg', Uint8List(0));
+      final result =
+          await sut.createProfileImage(profileImagePath, Uint8List(0));
+      verifyNever(
+        () => mockStoreService.put(StoreKey.currentUser, updatedUser),
+      );
+      verifyNever(() => mockUserRepo.update(updatedUser));
       expect(result, isNull);
     });
   });
diff --git a/mobile/test/modules/shared/sync_service_test.dart b/mobile/test/modules/shared/sync_service_test.dart
index f74c815997..7594c35fff 100644
--- a/mobile/test/modules/shared/sync_service_test.dart
+++ b/mobile/test/modules/shared/sync_service_test.dart
@@ -15,6 +15,7 @@ import 'package:immich_mobile/interfaces/partner_api.interface.dart';
 import 'package:immich_mobile/services/sync.service.dart';
 import 'package:mocktail/mocktail.dart';
 
+import '../../domain/service.mock.dart';
 import '../../infrastructure/repository.mock.dart';
 import '../../repository.mocks.dart';
 import '../../service.mocks.dart';
@@ -62,6 +63,7 @@ void main() {
         MockPartnerApiRepository();
     final MockUserApiRepository userApiRepository = MockUserApiRepository();
     final MockPartnerRepository partnerRepository = MockPartnerRepository();
+    final MockUserService userService = MockUserService();
 
     final owner = UserDto(
       uid: "1",
@@ -101,11 +103,12 @@ void main() {
         exifInfoRepository,
         partnerRepository,
         userRepository,
-        StoreService.I,
+        userService,
         eTagRepository,
         partnerApiRepository,
         userApiRepository,
       );
+      when(() => userService.getMyUser()).thenReturn(owner);
       when(() => eTagRepository.get(owner.id))
           .thenAnswer((_) async => ETag(id: owner.uid, time: DateTime.now()));
       when(() => eTagRepository.deleteByIds(["1"])).thenAnswer((_) async {});
diff --git a/mobile/test/services/album.service_test.dart b/mobile/test/services/album.service_test.dart
index 993456ad99..0efd695560 100644
--- a/mobile/test/services/album.service_test.dart
+++ b/mobile/test/services/album.service_test.dart
@@ -31,6 +31,8 @@ void main() {
     albumMediaRepository = MockAlbumMediaRepository();
     albumApiRepository = MockAlbumApiRepository();
 
+    when(() => userService.getMyUser()).thenReturn(UserStub.user1);
+
     when(() => albumRepository.transaction<void>(any())).thenAnswer(
       (call) => (call.positionalArguments.first as Function).call(),
     );
@@ -40,6 +42,7 @@ void main() {
 
     sut = AlbumService(
       syncService,
+      userService,
       entityService,
       albumRepository,
       assetRepository,