flutter_secure_storage: Data of FlutterSecureStorage instance is null on iOS but not on Android

Hello, this code works on my Android app but not iOS. I tested it on a physical device and simulator.

class _MyHomePageState extends State<MyHomePage> {
  final storage = const FlutterSecureStorage();

  Future _containsKey() async {
    return storage.containsKey(key: "conciergeRowGuid");
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
        future: _containsKey(),
        builder: (context, snapshot) {
          return (snapshot.data == false)
              ? Scaffold(
                  backgroundColor: Colors.white,
                  body: Container(child: Text("not loaded"))
                )
              : FutureBuilder(
                  future: storage.read(key: "conciergeRowGuid"),
                  builder: (context, snapshot) {
                    if (snapshot.data == null) {
                      return SizedBox(
                        height: MediaQuery.of(context).size.height - 135,
                        width: MediaQuery.of(context).size.width,
                        child: Column(
                          mainAxisAlignment: MainAxisAlignment.center,
                          crossAxisAlignment: CrossAxisAlignment.center,
                          children: const [
                            CircularProgressIndicator(
                              color: Color.fromARGB(255, 176, 64, 251),
                            ),
                          ],
                        ),
                      );
                    }
                    return Container(child: Text("loaded"));
                  });
        });
  }

In the iOS app, snapshot.data is always null. Digging into the iOS code of the Flutter Secure Storage, the functions of containsKey, write, read, readAll, deleteAll, all have groupId as nil. Also, OSStatus status has the error code 25300 which means errSecItemNotFound . And the return NSString *value is also nil. There is a similar issue #107 but the fix suggested is not working for me.

Specs: Flutter 2.10.4 flutter_secure_storage: ^5.0.2 MacOS Big Sur 11.6 Tested on:

  • iPhone 13 Simulator iOS 15.0
  • Physical iPhone 11 iOS 14.6
  • Physical iPhone SE (2nd gen) iOS 15.4.1

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 15

Most upvoted comments

I am just having the same problem, android and web can normally get the value, on Ios, although the contains(key) is true, the read() gets null

Currently I followed the first step in this:

# ios/Runner/Runner.entitlements

+ <key>keychain-access-groups</key>
+   <array>
+      <string>$(AppIdentifierPrefix)*</string>
+   </array>

answer and everything working. @juliansteenbakker I will check the version as soon I have a break. You think that version would replace the fix I added above?

For us, both read is always null, contains is always false and write doesn’t throw any error (So assuming that it’s storing). This issue is replicable across all scenarios on iOS 17.2 Emulator.

We have even tried these steps

  • iOptions: IOSOptions(accessibility: KeychainAccessibility.first_unlock),
  • Set MinSDKversion for IOS to 13
  • <string>$(AppIdentifierPrefix)*</string>

None of them has fixed the issue.

For me the main issue went away, when I set the MinSDKversion for IOS to 13 (see https://docs.amplify.aws/flutter/start/project-setup/platform-setup/#enable-keychain)

I had a similar issue but only when the app went to the background and the phone was locked, turned out the keychain gets locked after a while

const FlutterSecureStorage(
        iOptions: IOSOptions(accessibility: KeychainAccessibility.first_unlock),
      ),

Resolved the issue for me