You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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,未开启会导致存储失败。
  • 增加异常捕获:所有读写操作都包裹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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 14:54:06