Flutter Secure Storage v5.0.2无法读写键值该如何排查?
FlutterSecureStorage v5.0.2 问题排查与修正方案
1. 现有代码的已知问题
你当前的封装存在两处会直接导致读写异常的问题:
- 读写操作的平台选项不统一:只有write、readAll、deleteAll方法传入了iOptions和aOptions,read、delete方法未传入对应参数。flutter_secure_storage 5.x版本要求读写的平台配置必须完全一致,否则会出现写入成功但读不到值的问题(不同配置对应不同的加密分区/存储域)。
- 异步方法无返回Future:
deleteAll和writeSecureData当前返回值为void,调用方无法通过await等待操作完成,若写完后立刻读,大概率会因为写入未完成拿到空值。
修正后的工具类代码
import 'package:flutter_secure_storage/flutter_secure_storage.dart'; class SecureStorage { final _storage = const FlutterSecureStorage(); IOSOptions _getIOSOptions() => const IOSOptions( accessibility: IOSAccessibility.first_unlock, ); AndroidOptions _getAndroidOptions() => const AndroidOptions( encryptedSharedPreferences: true, ); Future<Map<String, String>> readAll() async { return await _storage.readAll( iOptions: _getIOSOptions(), aOptions: _getAndroidOptions()); } Future<void> deleteAll() async { await _storage.deleteAll( iOptions: _getIOSOptions(), aOptions: _getAndroidOptions()); } Future<String?> readSecureData(String key) async { // 读操作补全平台选项 return await _storage.read( key: key, iOptions: _getIOSOptions(), aOptions: _getAndroidOptions(), ); } Future<void> deleteSecureData(String key) async { // 删除操作补全平台选项 return await _storage.delete( key: key, iOptions: _getIOSOptions(), aOptions: _getAndroidOptions(), ); } // 改为返回Future,支持调用方await Future<void> writeSecureData(String key, String value) async { await _storage.write( key: key, value: value, iOptions: _getIOSOptions(), aOptions: _getAndroidOptions(), ); } } final secureStorage = SecureStorage();
2. 通用排查步骤
如果修正代码后仍然存在读写异常,按以下顺序排查:
- 验证基础链路:写入操作后立刻调用
readAll()打印所有存储的键值对,确认值确实写入成功,注意必须等write的Future完成后再执行读操作。 - 安卓端专项检查:
- 确认项目
minSdkVersion >= 18,encryptedSharedPreferences特性要求最低安卓版本为18,低于该版本会抛出异常。 - 如果是升级app后读不到旧值,确认旧版本是否开启了encryptedSharedPreferences,开关切换会导致旧加密数据无法被读取。
- 确认项目
- iOS端专项检查:
- 你设置的accessibility为
first_unlock,意味着手机重启后第一次解锁前,无法读取存储的值,若app有后台唤醒场景需要调整accessibility等级。 - 确认Xcode中已经开启Keychain Sharing能力,路径为Signing & Capabilities -> 添加Keychain Sharing,未开启会导致存储失败。
- 你设置的accessibility为
- 增加异常捕获:所有读写操作都包裹try-catch,平台侧的错误会直接通过异常抛出,可快速定位问题:
try { await secureStorage.writeSecureData('username', username); } catch (e) { print('存储操作异常:$e'); } - 原生层验证:安卓可以通过Android Studio的Device File Explorer,查看data/data/你的包名/shared_prefs目录下的xml文件,确认加密存储数据是否存在;iOS可以通过Xcode的Devices and Simulators功能,下载app容器文件查看Keychain存储状态。
内容的提问来源于stack exchange,提问作者KeroJohn97
相关产品推荐
相关产品推荐

