use a centralized version of flutter secure storage

This commit is contained in:
otsmr 2026-04-25 01:12:00 +02:00
parent 646b9c22d3
commit db9d9022fd
13 changed files with 77 additions and 53 deletions

View file

@ -3,7 +3,6 @@ import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:sentry_flutter/sentry_flutter.dart'; import 'package:sentry_flutter/sentry_flutter.dart';
import 'package:twonly/app.dart'; import 'package:twonly/app.dart';
@ -28,6 +27,7 @@ import 'package:twonly/src/services/notifications/setup.notifications.dart';
import 'package:twonly/src/services/user.service.dart'; import 'package:twonly/src/services/user.service.dart';
import 'package:twonly/src/utils/avatars.dart'; import 'package:twonly/src/utils/avatars.dart';
import 'package:twonly/src/utils/log.dart'; import 'package:twonly/src/utils/log.dart';
import 'package:twonly/src/utils/secure_storage.dart';
import 'package:twonly/src/utils/storage.dart'; import 'package:twonly/src/utils/storage.dart';
/// This function is used to initialized the absolute minimum so it /// This function is used to initialized the absolute minimum so it
@ -56,13 +56,23 @@ void main() async {
await initFCMService(); await initFCMService();
final userExists = await userService.tryInit(); var userExists = false;
var storageError = false;
try {
userExists = await userService.tryInit();
} catch (e) {
Log.error('Failed to initialize user session due to storage error: $e');
storageError = true;
}
final dbFile = File('${AppEnvironment.supportDir}/twonly.sqlite');
final dbExists = dbFile.existsSync();
if (Platform.isIOS && userExists) { if (Platform.isIOS && userExists) {
final db = File('${AppEnvironment.supportDir}/twonly.sqlite'); if (!dbExists) {
if (!db.existsSync()) {
Log.error('[twonly] IOS: App was removed and then reinstalled again...'); Log.error('[twonly] IOS: App was removed and then reinstalled again...');
await const FlutterSecureStorage().deleteAll(); await SecureStorage.instance.deleteAll();
userExists = false;
} }
} }
@ -80,9 +90,21 @@ void main() async {
unawaited(performTwonlySafeBackup()); unawaited(performTwonlySafeBackup());
unawaited(initializeBackgroundTaskManager()); unawaited(initializeBackgroundTaskManager());
} else { } else if (!storageError) {
Log.info('User is not yet register. Ensure all local data is removed.'); if (!dbExists) {
Log.info(
'User is not yet registered and no database found. Ensuring clean state.',
);
await deleteLocalUserData(); await deleteLocalUserData();
} else {
Log.error(
'User not found in secure storage, but database exists. Skipping destructive wipe.',
);
}
} else {
Log.error(
'Storage error occurred and database exists. Skipping wipe to prevent data loss.',
);
} }
final settingsController = SettingsChangeProvider(); final settingsController = SettingsChangeProvider();

View file

@ -1,14 +1,14 @@
import 'dart:collection'; import 'dart:collection';
import 'dart:convert'; import 'dart:convert';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:libsignal_protocol_dart/libsignal_protocol_dart.dart'; import 'package:libsignal_protocol_dart/libsignal_protocol_dart.dart';
import 'package:twonly/src/constants/secure_storage.keys.dart'; import 'package:twonly/src/constants/secure_storage.keys.dart';
import 'package:twonly/src/utils/secure_storage.dart';
class SignalSignedPreKeyStore extends SignedPreKeyStore { class SignalSignedPreKeyStore extends SignedPreKeyStore {
Future<HashMap<int, Uint8List>> getStore() async { Future<HashMap<int, Uint8List>> getStore() async {
const storage = FlutterSecureStorage(); final storeSerialized = await SecureStorage.instance.read(
final storeSerialized = await storage.read(
key: SecureStorageKeys.signalSignedPreKey, key: SecureStorageKeys.signalSignedPreKey,
); );
final store = HashMap<int, Uint8List>(); final store = HashMap<int, Uint8List>();
@ -24,13 +24,12 @@ class SignalSignedPreKeyStore extends SignedPreKeyStore {
} }
Future<void> safeStore(HashMap<int, Uint8List> store) async { Future<void> safeStore(HashMap<int, Uint8List> store) async {
const storage = FlutterSecureStorage();
final storeHashMap = <List<dynamic>>[]; final storeHashMap = <List<dynamic>>[];
for (final item in store.entries) { for (final item in store.entries) {
storeHashMap.add([item.key, base64Encode(item.value)]); storeHashMap.add([item.key, base64Encode(item.value)]);
} }
final storeSerialized = json.encode(storeHashMap); final storeSerialized = json.encode(storeHashMap);
await storage.write( await SecureStorage.instance.write(
key: SecureStorageKeys.signalSignedPreKey, key: SecureStorageKeys.signalSignedPreKey,
value: storeSerialized, value: storeSerialized,
); );

View file

@ -11,7 +11,6 @@ import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:drift/drift.dart'; import 'package:drift/drift.dart';
import 'package:fixnum/fixnum.dart'; import 'package:fixnum/fixnum.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
// ignore: implementation_imports // ignore: implementation_imports
import 'package:libsignal_protocol_dart/src/ecc/ed25519.dart'; import 'package:libsignal_protocol_dart/src/ecc/ed25519.dart';
import 'package:mutex/mutex.dart'; import 'package:mutex/mutex.dart';
@ -44,6 +43,7 @@ import 'package:twonly/src/services/user_study.service.dart';
import 'package:twonly/src/utils/keyvalue.dart'; import 'package:twonly/src/utils/keyvalue.dart';
import 'package:twonly/src/utils/log.dart'; import 'package:twonly/src/utils/log.dart';
import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/utils/misc.dart';
import 'package:twonly/src/utils/secure_storage.dart';
import 'package:web_socket_channel/io.dart'; import 'package:web_socket_channel/io.dart';
final lockConnecting = Mutex(); final lockConnecting = Mutex();
@ -417,8 +417,7 @@ class ApiService {
} }
Future<bool> tryAuthenticateWithToken(int userId) async { Future<bool> tryAuthenticateWithToken(int userId) async {
const storage = FlutterSecureStorage(); final apiAuthToken = await SecureStorage.instance.read(
final apiAuthToken = await storage.read(
key: SecureStorageKeys.apiAuthToken, key: SecureStorageKeys.apiAuthToken,
); );
final user = await getUser(); final user = await getUser();
@ -518,8 +517,7 @@ class ApiService {
final apiAuthToken = result2.value.authtoken as Uint8List; final apiAuthToken = result2.value.authtoken as Uint8List;
final apiAuthTokenB64 = base64Encode(apiAuthToken); final apiAuthTokenB64 = base64Encode(apiAuthToken);
const storage = FlutterSecureStorage(); await SecureStorage.instance.write(
await storage.write(
key: SecureStorageKeys.apiAuthToken, key: SecureStorageKeys.apiAuthToken,
value: apiAuthTokenB64, value: apiAuthTokenB64,
); );

View file

@ -8,7 +8,6 @@ import 'package:cryptography_flutter_plus/cryptography_flutter_plus.dart';
import 'package:cryptography_plus/cryptography_plus.dart'; import 'package:cryptography_plus/cryptography_plus.dart';
import 'package:drift/drift.dart'; import 'package:drift/drift.dart';
import 'package:fixnum/fixnum.dart'; import 'package:fixnum/fixnum.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
import 'package:mutex/mutex.dart'; import 'package:mutex/mutex.dart';
import 'package:twonly/globals.dart'; import 'package:twonly/globals.dart';
@ -26,6 +25,7 @@ import 'package:twonly/src/services/flame.service.dart';
import 'package:twonly/src/services/mediafiles/mediafile.service.dart'; import 'package:twonly/src/services/mediafiles/mediafile.service.dart';
import 'package:twonly/src/utils/log.dart'; import 'package:twonly/src/utils/log.dart';
import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/utils/misc.dart';
import 'package:twonly/src/utils/secure_storage.dart';
import 'package:workmanager/workmanager.dart' hide TaskStatus; import 'package:workmanager/workmanager.dart' hide TaskStatus;
final lockRetransmission = Mutex(); final lockRetransmission = Mutex();
@ -607,7 +607,7 @@ Future<void> _uploadUploadRequest(MediaFileService media) async {
return null; return null;
} }
final apiAuthTokenRaw = await const FlutterSecureStorage().read( final apiAuthTokenRaw = await SecureStorage.instance.read(
key: SecureStorageKeys.apiAuthToken, key: SecureStorageKeys.apiAuthToken,
); );

View file

@ -9,7 +9,6 @@ import 'package:cryptography_flutter_plus/cryptography_flutter_plus.dart';
import 'package:cryptography_plus/cryptography_plus.dart'; import 'package:cryptography_plus/cryptography_plus.dart';
import 'package:drift/drift.dart'; import 'package:drift/drift.dart';
import 'package:drift_flutter/drift_flutter.dart'; import 'package:drift_flutter/drift_flutter.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:path/path.dart'; import 'package:path/path.dart';
import 'package:twonly/globals.dart'; import 'package:twonly/globals.dart';
import 'package:twonly/locator.dart'; import 'package:twonly/locator.dart';
@ -21,6 +20,7 @@ import 'package:twonly/src/services/backup/common.backup.dart';
import 'package:twonly/src/services/user.service.dart'; import 'package:twonly/src/services/user.service.dart';
import 'package:twonly/src/utils/log.dart'; import 'package:twonly/src/utils/log.dart';
import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/utils/misc.dart';
import 'package:twonly/src/utils/secure_storage.dart';
Future<void> performTwonlySafeBackup({bool force = false}) async { Future<void> performTwonlySafeBackup({bool force = false}) async {
if (userService.currentUser.twonlySafeBackup == null) { if (userService.currentUser.twonlySafeBackup == null) {
@ -84,12 +84,15 @@ Future<void> performTwonlySafeBackup({bool force = false}) async {
// ignore: inference_failure_on_collection_literal // ignore: inference_failure_on_collection_literal
final secureStorageBackup = {}; final secureStorageBackup = {};
const storage = FlutterSecureStorage(); secureStorageBackup[SecureStorageKeys.signalIdentity] = await SecureStorage
secureStorageBackup[SecureStorageKeys.signalIdentity] = await storage.read( .instance
.read(
key: SecureStorageKeys.signalIdentity, key: SecureStorageKeys.signalIdentity,
); );
secureStorageBackup[SecureStorageKeys.signalSignedPreKey] = await storage secureStorageBackup[SecureStorageKeys.signalSignedPreKey] =
.read(key: SecureStorageKeys.signalSignedPreKey); await SecureStorage.instance.read(
key: SecureStorageKeys.signalSignedPreKey,
);
final userBackup = await getUser(); final userBackup = await getUser();
if (userBackup == null) return; if (userBackup == null) return;
@ -129,7 +132,7 @@ Future<void> performTwonlySafeBackup({bool force = false}) async {
force = true; force = true;
} }
final lastHash = await storage.read( final lastHash = await SecureStorage.instance.read(
key: SecureStorageKeys.twonlySafeLastBackupHash, key: SecureStorageKeys.twonlySafeLastBackupHash,
); );
@ -139,7 +142,8 @@ Future<void> performTwonlySafeBackup({bool force = false}) async {
return; return;
} }
} }
await storage.write(
await SecureStorage.instance.write(
key: SecureStorageKeys.twonlySafeLastBackupHash, key: SecureStorageKeys.twonlySafeLastBackupHash,
value: backupHash, value: backupHash,
); );

View file

@ -6,7 +6,6 @@ import 'dart:io';
import 'package:cryptography_flutter_plus/cryptography_flutter_plus.dart'; import 'package:cryptography_flutter_plus/cryptography_flutter_plus.dart';
import 'package:cryptography_plus/cryptography_plus.dart'; import 'package:cryptography_plus/cryptography_plus.dart';
import 'package:drift/drift.dart'; import 'package:drift/drift.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
import 'package:path/path.dart'; import 'package:path/path.dart';
import 'package:twonly/globals.dart'; import 'package:twonly/globals.dart';
@ -16,6 +15,7 @@ import 'package:twonly/src/model/protobuf/client/generated/backup.pb.dart';
import 'package:twonly/src/services/backup/common.backup.dart'; import 'package:twonly/src/services/backup/common.backup.dart';
import 'package:twonly/src/services/user.service.dart'; import 'package:twonly/src/services/user.service.dart';
import 'package:twonly/src/utils/log.dart'; import 'package:twonly/src/utils/log.dart';
import 'package:twonly/src/utils/secure_storage.dart';
Future<void> recoverBackup( Future<void> recoverBackup(
String username, String username,
@ -92,7 +92,7 @@ Future<void> handleBackupData(
); );
await originalDatabase.writeAsBytes(backupContent.twonlyDatabase); await originalDatabase.writeAsBytes(backupContent.twonlyDatabase);
const storage = FlutterSecureStorage(); const storage = SecureStorage.instance;
final secureStorage = jsonDecode(backupContent.secureStorageJson); final secureStorage = jsonDecode(backupContent.secureStorageJson);

View file

@ -2,7 +2,6 @@ import 'dart:convert';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:clock/clock.dart'; import 'package:clock/clock.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:libsignal_protocol_dart/libsignal_protocol_dart.dart'; import 'package:libsignal_protocol_dart/libsignal_protocol_dart.dart';
import 'package:twonly/locator.dart'; import 'package:twonly/locator.dart';
import 'package:twonly/src/constants/secure_storage.keys.dart'; import 'package:twonly/src/constants/secure_storage.keys.dart';
@ -13,6 +12,7 @@ import 'package:twonly/src/services/signal/protocol_state.signal.dart';
import 'package:twonly/src/services/signal/utils.signal.dart'; import 'package:twonly/src/services/signal/utils.signal.dart';
import 'package:twonly/src/services/user.service.dart'; import 'package:twonly/src/services/user.service.dart';
import 'package:twonly/src/utils/log.dart'; import 'package:twonly/src/utils/log.dart';
import 'package:twonly/src/utils/secure_storage.dart';
Future<IdentityKeyPair?> getSignalIdentityKeyPair() async { Future<IdentityKeyPair?> getSignalIdentityKeyPair() async {
final signalIdentity = await getSignalIdentity(); final signalIdentity = await getSignalIdentity();
@ -79,8 +79,7 @@ Future<List<PreKeyRecord>> signalGetPreKeys() async {
Future<SignalIdentity?> getSignalIdentity() async { Future<SignalIdentity?> getSignalIdentity() async {
try { try {
const storage = FlutterSecureStorage(); var signalIdentityJson = await SecureStorage.instance.read(
var signalIdentityJson = await storage.read(
key: SecureStorageKeys.signalIdentity, key: SecureStorageKeys.signalIdentity,
); );
if (signalIdentityJson == null) { if (signalIdentityJson == null) {
@ -102,9 +101,7 @@ Future<Uint8List> getUserPublicKey() async {
} }
Future<void> createIfNotExistsSignalIdentity() async { Future<void> createIfNotExistsSignalIdentity() async {
const storage = FlutterSecureStorage(); final signalIdentity = await SecureStorage.instance.read(
final signalIdentity = await storage.read(
key: SecureStorageKeys.signalIdentity, key: SecureStorageKeys.signalIdentity,
); );
@ -132,7 +129,7 @@ Future<void> createIfNotExistsSignalIdentity() async {
registrationId: registrationId, registrationId: registrationId,
); );
await storage.write( await SecureStorage.instance.write(
key: SecureStorageKeys.signalIdentity, key: SecureStorageKeys.signalIdentity,
value: jsonEncode(storedSignalIdentity), value: jsonEncode(storedSignalIdentity),
); );

View file

@ -11,6 +11,7 @@ import 'package:twonly/src/model/json/userdata.model.dart';
import 'package:twonly/src/providers/purchases.provider.dart'; import 'package:twonly/src/providers/purchases.provider.dart';
import 'package:twonly/src/services/subscription.service.dart'; import 'package:twonly/src/services/subscription.service.dart';
import 'package:twonly/src/utils/log.dart'; import 'package:twonly/src/utils/log.dart';
import 'package:twonly/src/utils/secure_storage.dart';
class UserService { class UserService {
late UserData currentUser; late UserData currentUser;
@ -45,18 +46,16 @@ Future<bool> isUserCreated() async {
Future<UserData?> getUser() async { Future<UserData?> getUser() async {
try { try {
final userJson = await const FlutterSecureStorage().read( final userDataJson = await SecureStorage.instance.read(
key: SecureStorageKeys.userData, key: SecureStorageKeys.userData,
); );
if (userJson == null) { if (userDataJson == null) {
return null; return null;
} }
final userMap = jsonDecode(userJson) as Map<String, dynamic>; return UserData.fromJson(jsonDecode(userDataJson) as Map<String, dynamic>);
final user = UserData.fromJson(userMap);
return user;
} catch (e) { } catch (e) {
Log.error('Error getting user: $e'); Log.error('could not load user: $e');
return null; rethrow; // Rethrow instead of returning null to distinguish error from missing user
} }
} }

View file

@ -0,0 +1,5 @@
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
class SecureStorage {
static const FlutterSecureStorage instance = FlutterSecureStorage();
}

View file

@ -1,11 +1,11 @@
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'package:twonly/src/utils/secure_storage.dart';
Future<bool> deleteLocalUserData() async { Future<bool> deleteLocalUserData() async {
final appDir = await getApplicationSupportDirectory(); final appDir = await getApplicationSupportDirectory();
if (appDir.existsSync()) { if (appDir.existsSync()) {
appDir.deleteSync(recursive: true); appDir.deleteSync(recursive: true);
} }
await const FlutterSecureStorage().deleteAll(); await SecureStorage.instance.deleteAll();
return true; return true;
} }

View file

@ -5,7 +5,6 @@ import 'dart:convert';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:twonly/locator.dart'; import 'package:twonly/locator.dart';
import 'package:twonly/src/constants/routes.keys.dart'; import 'package:twonly/src/constants/routes.keys.dart';
@ -16,6 +15,7 @@ import 'package:twonly/src/services/signal/identity.signal.dart';
import 'package:twonly/src/utils/log.dart'; import 'package:twonly/src/utils/log.dart';
import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/utils/misc.dart';
import 'package:twonly/src/utils/pow.dart'; import 'package:twonly/src/utils/pow.dart';
import 'package:twonly/src/utils/secure_storage.dart';
import 'package:twonly/src/utils/storage.dart'; import 'package:twonly/src/utils/storage.dart';
import 'package:twonly/src/visual/components/alert.dialog.dart'; import 'package:twonly/src/visual/components/alert.dialog.dart';
import 'package:twonly/src/visual/views/groups/group.view.dart'; import 'package:twonly/src/visual/views/groups/group.view.dart';
@ -138,7 +138,7 @@ class _RegisterViewState extends State<RegisterView> {
subscriptionPlan: 'Preview', subscriptionPlan: 'Preview',
)..appVersion = 62; )..appVersion = 62;
await const FlutterSecureStorage().write( await SecureStorage.instance.write(
key: SecureStorageKeys.userData, key: SecureStorageKeys.userData,
value: jsonEncode(userData), value: jsonEncode(userData),
); );

View file

@ -3,7 +3,6 @@ import 'dart:convert';
import 'package:device_info_plus/device_info_plus.dart'; import 'package:device_info_plus/device_info_plus.dart';
import 'package:fixnum/fixnum.dart'; import 'package:fixnum/fixnum.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
import 'package:package_info_plus/package_info_plus.dart'; import 'package:package_info_plus/package_info_plus.dart';
@ -12,6 +11,7 @@ import 'package:twonly/src/constants/secure_storage.keys.dart';
import 'package:twonly/src/model/protobuf/api/http/http_requests.pb.dart'; import 'package:twonly/src/model/protobuf/api/http/http_requests.pb.dart';
import 'package:twonly/src/utils/log.dart'; import 'package:twonly/src/utils/log.dart';
import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/utils/misc.dart';
import 'package:twonly/src/utils/secure_storage.dart';
import 'package:twonly/src/visual/views/settings/help/contact_us/submit_message.view.dart'; import 'package:twonly/src/visual/views/settings/help/contact_us/submit_message.view.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
@ -48,7 +48,7 @@ class _ContactUsState extends State<ContactUsView> {
final uploadRequestBytes = uploadRequest.writeToBuffer(); final uploadRequestBytes = uploadRequest.writeToBuffer();
final apiAuthTokenRaw = await const FlutterSecureStorage().read( final apiAuthTokenRaw = await SecureStorage.instance.read(
key: SecureStorageKeys.apiAuthToken, key: SecureStorageKeys.apiAuthToken,
); );
if (apiAuthTokenRaw == null) { if (apiAuthTokenRaw == null) {

View file

@ -3,7 +3,6 @@ import 'dart:io';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:hashlib/random.dart'; import 'package:hashlib/random.dart';
import 'package:twonly/locator.dart'; import 'package:twonly/locator.dart';
import 'package:twonly/src/constants/secure_storage.keys.dart'; import 'package:twonly/src/constants/secure_storage.keys.dart';
@ -12,6 +11,7 @@ import 'package:twonly/src/services/notifications/fcm.notifications.dart';
import 'package:twonly/src/services/notifications/pushkeys.notifications.dart'; import 'package:twonly/src/services/notifications/pushkeys.notifications.dart';
import 'package:twonly/src/services/user.service.dart'; import 'package:twonly/src/services/user.service.dart';
import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/utils/misc.dart';
import 'package:twonly/src/utils/secure_storage.dart';
import 'package:twonly/src/visual/components/alert.dialog.dart'; import 'package:twonly/src/visual/components/alert.dialog.dart';
class NotificationView extends StatefulWidget { class NotificationView extends StatefulWidget {
@ -33,9 +33,9 @@ class _NotificationViewState extends State<NotificationView> {
await initFCMAfterAuthenticated(force: true); await initFCMAfterAuthenticated(force: true);
final storedToken = await (const FlutterSecureStorage().read( final storedToken = await SecureStorage.instance.read(
key: SecureStorageKeys.googleFcm, key: SecureStorageKeys.googleFcm,
)); );
await setupNotificationWithUsers(force: true); await setupNotificationWithUsers(force: true);