Skip to content

Commit 3a514bb

Browse files
committed
feat: migrate flutter_secure_storage to v10
- Set Android minSdk to 23 in build.gradle.kts - Use explicitly configured AndroidOptions with encryptedSharedPreferences - Add error handling (try-catch) for all secure storage operations - Centralize AndroidOptions configuration in constants.dart
1 parent 41260bd commit 3a514bb

File tree

5 files changed

+79
-32
lines changed

5 files changed

+79
-32
lines changed

android/app/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ println("PROJECT_ID: $projectId")
3737
applicationId = "com.resonate.resonate"
3838
// You can update the following values to match your application needs.
3939
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
40-
minSdk = flutter.minSdkVersion
40+
minSdk = 23
4141
targetSdk = flutter.targetSdkVersion
4242
versionCode = flutter.versionCode.toInt()
4343
versionName = flutter.versionName

lib/main.dart

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -58,15 +58,20 @@ Future<void> main() async {
5858
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
5959
await GetStorage.init();
6060
Get.put(AboutAppScreenController());
61-
languageLocale =
62-
await FlutterSecureStorage().read(key: "languageLocale") ?? "en";
63-
final String? savedModel = await FlutterSecureStorage().read(
64-
key: "whisperModel",
65-
);
66-
currentWhisperModel.value = WhisperModel.values.firstWhere(
67-
(model) => model.modelName == (savedModel ?? "base"),
68-
orElse: () => WhisperModel.base,
69-
);
61+
try {
62+
const storage = FlutterSecureStorage(aOptions: androidOptions);
63+
languageLocale = await storage.read(key: "languageLocale") ?? "en";
64+
final String? savedModel = await storage.read(key: "whisperModel");
65+
currentWhisperModel.value = WhisperModel.values.firstWhere(
66+
(model) => model.modelName == (savedModel ?? "base"),
67+
orElse: () => WhisperModel.base,
68+
);
69+
} catch (e) {
70+
log("SecureStorage init error: $e");
71+
// Fallback defaults
72+
languageLocale = "en";
73+
currentWhisperModel.value = WhisperModel.base;
74+
}
7075
runApp(const MyApp());
7176
}
7277

lib/services/room_service.dart

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,16 @@ class RoomService {
108108
: response["livekit_socket_url"];
109109

110110
// Store Livekit Url and Token in Secure Storage
111-
const storage = FlutterSecureStorage();
112-
await storage.write(key: "createdRoomAdminToken", value: livekitToken);
113-
await storage.write(key: "createdRoomLivekitUrl", value: livekitSocketUrl);
111+
try {
112+
const storage = FlutterSecureStorage(aOptions: androidOptions);
113+
await storage.write(key: "createdRoomAdminToken", value: livekitToken);
114+
await storage.write(
115+
key: "createdRoomLivekitUrl",
116+
value: livekitSocketUrl,
117+
);
118+
} catch (e) {
119+
Get.snackbar("Error", "Failed to save room token: $e");
120+
}
114121

115122
String myDocId = await addParticipantToAppwriteCollection(
116123
roomId: appwriteRoomDocId,
@@ -138,9 +145,16 @@ class RoomService {
138145
: response["livekit_socket_url"];
139146

140147
// Store Livekit Url and Token in Secure Storage
141-
const storage = FlutterSecureStorage();
142-
await storage.write(key: "createdRoomAdminToken", value: livekitToken);
143-
await storage.write(key: "createdRoomLivekitUrl", value: livekitSocketUrl);
148+
try {
149+
const storage = FlutterSecureStorage(aOptions: androidOptions);
150+
await storage.write(key: "createdRoomAdminToken", value: livekitToken);
151+
await storage.write(
152+
key: "createdRoomLivekitUrl",
153+
value: livekitSocketUrl,
154+
);
155+
} catch (e) {
156+
Get.snackbar("Error", "Failed to save room token: $e");
157+
}
144158

145159
await joinLiveKitRoom(livekitSocketUrl, livekitToken, isLiveChapter: true);
146160

@@ -162,20 +176,32 @@ class RoomService {
162176
}
163177

164178
static Future deleteLiveChapterRoom({required roomId}) async {
165-
const storage = FlutterSecureStorage();
179+
try {
180+
const storage = FlutterSecureStorage(aOptions: androidOptions);
166181

167-
// Delete room on livekit and roomdoc on appwrite
168-
String? livekitToken = await storage.read(key: "createdRoomAdminToken");
169-
await apiService.deleteLiveChapterRoom(roomId, livekitToken!);
182+
// Delete room on livekit and roomdoc on appwrite
183+
String? livekitToken = await storage.read(key: "createdRoomAdminToken");
184+
if (livekitToken != null) {
185+
await apiService.deleteLiveChapterRoom(roomId, livekitToken);
186+
}
187+
} catch (e) {
188+
print("Error deleting live chapter room: $e");
189+
}
170190
}
171191

172192
static Future deleteRoom({required roomId}) async {
173193
RoomsController roomsController = Get.find<RoomsController>();
174-
const storage = FlutterSecureStorage();
194+
try {
195+
const storage = FlutterSecureStorage(aOptions: androidOptions);
175196

176-
// Delete room on livekit and roomdoc on appwrite
177-
String? livekitToken = await storage.read(key: "createdRoomAdminToken");
178-
await apiService.deleteRoom(roomId, livekitToken!);
197+
// Delete room on livekit and roomdoc on appwrite
198+
String? livekitToken = await storage.read(key: "createdRoomAdminToken");
199+
if (livekitToken != null) {
200+
await apiService.deleteRoom(roomId, livekitToken);
201+
}
202+
} catch (e) {
203+
print("Error deleting room: $e");
204+
}
179205

180206
// Get all participant documents and delete them
181207
DocumentList participantDocsRef = await roomsController.databases

lib/utils/constants.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,16 @@
22

33
// Appwrite Project Constants
44

5+
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
56
import 'package:get/get.dart';
67
import 'package:whisper_flutter_new/whisper_flutter_new.dart';
78

9+
const androidOptions = AndroidOptions(
10+
encryptedSharedPreferences: true,
11+
migrateOnAlgorithmChange: true,
12+
resetOnError: true,
13+
);
14+
815
const String baseDomain = String.fromEnvironment(
916
'APPWRITE_BASE_DOMAIN',
1017
defaultValue: '10.12.78.30',

lib/views/screens/app_preferences_screen.dart

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -138,10 +138,13 @@ class _AppPreferencesScreenState extends State<AppPreferencesScreen> {
138138
onValuePicked: (Language language) async {
139139
Get.updateLocale(Locale(language.isoCode));
140140

141-
await FlutterSecureStorage().write(
142-
key: "languageLocale",
143-
value: language.isoCode,
144-
);
141+
try {
142+
await const FlutterSecureStorage(
143+
aOptions: androidOptions,
144+
).write(key: "languageLocale", value: language.isoCode);
145+
} catch (e) {
146+
// log error
147+
}
145148
},
146149
languages: AppLocalizations.supportedLocales
147150
.map((locale) => Language.fromIsoCode(locale.languageCode))
@@ -207,10 +210,16 @@ class _AppPreferencesScreenState extends State<AppPreferencesScreen> {
207210
onTap: () async {
208211
currentWhisperModel.value = modelData['model'];
209212

210-
await FlutterSecureStorage().write(
211-
key: "whisperModel",
212-
value: modelData['model'].modelName,
213-
);
213+
try {
214+
await const FlutterSecureStorage(
215+
aOptions: androidOptions,
216+
).write(
217+
key: "whisperModel",
218+
value: modelData['model'].modelName,
219+
);
220+
} catch (e) {
221+
// log error
222+
}
214223
},
215224
leading: Container(
216225
padding: EdgeInsets.all(UiSizes.width_10),

0 commit comments

Comments
 (0)