flutter_secure_storage: OperationError when calling `read()` on web

I’m getting the following error when calling read() on web, only if the key exists in storage. It works fine if the key does not exist. Calling containsKey() returns the correct value and does not produce this error.

Error: OperationError


    at Object.createErrorWithStack (http://localhost:5000/dart_sdk.js:5080:12)
    at Function._throw (http://localhost:5000/dart_sdk.js:20337:18)
    at Function.throwWithStackTrace (http://localhost:5000/dart_sdk.js:20334:18)
    at async._AsyncCallbackEntry.new.callback (http://localhost:5000/dart_sdk.js:40851:18)
    at Object._microtaskLoop (http://localhost:5000/dart_sdk.js:40708:13)
    at _startMicrotaskLoop (http://localhost:5000/dart_sdk.js:40714:13)
    at http://localhost:5000/dart_sdk.js:36191:9

This seems to be triggered from invoking the callback function in the following block:

    static _scheduleImmediateWithPromise(callback) {
      dart.addAsyncCallback();
      dart.global.Promise.resolve(null).then(() => {
        dart.removeAsyncCallback();
        callback();
      });
    }

I’m running Chromium 99.0.4844.82 on Arch Linux

Any thoughts on what this could be caused by?

NB: OperationError seems to be a DomException constant.

About this issue

  • Original URL
  • State: open
  • Created 2 years ago
  • Reactions: 14
  • Comments: 18

Most upvoted comments

I found a workaround for this issue. Make sure you’re not writing to the storage concurrently. Just await for each operation.

Consider having this function.

 Future<void> _writeString(String key, String value) async {
    const storage = FlutterSecureStorage();
    await storage.write(key: key, value: value);
  }

Calling it like this will produce read errors further on

_writeString("key1", "data");
_writeString("key2", "some other data");

but awaiting for them will work just fine

await _writeString("key1", "data");
await _writeString("key2", "some other data");

Encoding object as json works, thx @momrak

thank you apetroaeiandrei!

i added the synchronized package https://pub.dev/packages/synchronized, then wrapped my writes with:

    await _lock.synchronized(() async {
      await secureStorage!.write(key: key, value: value);
    });

operationerror issues gone!

I can confirm that storing it as json works. I wonder why. Maybe you can’t store multiple things? Anyway thanks @momrak !

Thanks for both tips! Managed to get it working by creating a class for my fields and save them as JSON strings. When doing a read on that field then I had no issue 🤷 Will see if I bump into it again

I had the same issue on macOS using the Web version.

My mistake was not using async / await properly - after adding “await” to ALL read / write functions, everything was working fine.

Hope that helps!

From what I can see the error is in

flutter_secure_storage_web.dart:152

  Future<String?> _decryptValue(
    String? cypherText,
    Map<String, String> options,
  ) async {
    if (cypherText == null) {
      return null;
    }

    final parts = cypherText.split(".");

    final iv = base64Decode(parts[0]);
    final algorithm = _getAlgorithm(iv);

    final decryptionKey = await _getEncryptionKey(algorithm, options);

    final value = base64Decode(parts[1]);

    final decryptedContent = await js_util.promiseToFuture<ByteBuffer>(
      crypto.decrypt(
        _getAlgorithm(iv),
        decryptionKey,
        Uint8List.fromList(value),
      ),
    );

    final plainText = utf8.decode(decryptedContent.asUint8List());

    return plainText;
  }

in this block

   final decryptedContent = await js_util.promiseToFuture<ByteBuffer>(
      crypto.decrypt(
        _getAlgorithm(iv),
        decryptionKey,
        Uint8List.fromList(value),
      ),
    );

Might this be relevant?

https://stackoverflow.com/questions/68160151/how-to-fix-this-operationerror-error-when-decrypting-data-with-crypto-api

Here is the relevant part of the stack trace

image