Closed jamesncl closed 2 years ago
Same problem here... please fix
It may be related to android backup feature, this plugin handles it very badly. The workaround is to delete all values on first run, or add try catch on every read and delete the value in case of errors.
did anyone get to fix this?
same here with 4.4.4 and 5.1.1 android version and 1.20.3 flutter version
I figure out that this happens with all other keychain package flutter_keychain , flutter_secured_storage , flutter_secure_storage , store_critical_data , impiger_securestroage i dont know why all package have same problem, may all have same codebase or there are problem with flutter itself or all make same bug
Hey @jamesncl Thanks for bringing things together. This problem was for quite a while and after spending some time on it and founding nothing, I stopped looking into the problem. Especially, I failed to replicate it in my app/on my devices.
However, I will check with the latest template for plugins and update the code accordingly.
I hit this yesterday and just figured it out! This is not related to the plugin directly. For secure storage to work on Android I had to modify the MainActivity.kt
file. (NOTE: from what I was reading, a lot of Flutter projects are using JAVA and the solution was slightly different but also in the MainActivity.java file)
Instead of MainActivity
extending FlutterActivity
, I had to extend from FlutterFragmentActivity
in order for Touch ID to work on Android. When I did this it broke the project but I normally work on iOS so I didn't notice. Flutter generates a class named GeneratedPluginRegistrant.java
. If this doesn't get called then Flutter can't see the plugin and you get the MissingPluginException
.
I believe FlutterActivity
is calling the plugin registration for you (at least in newer versions of Flutter). FlutterFragmentActivity
doesn't make that call so you need to explicitly do it. Here is my new MainActivity.kt
that is working:
import io.flutter.embedding.android.FlutterFragmentActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugins.GeneratedPluginRegistrant
class MainActivity: FlutterFragmentActivity() {
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
GeneratedPluginRegistrant.registerWith(flutterEngine)
}
}
If you have a MainActivity.java file, here is what I found online that I had to translate to Kotlin. Note that the only difference is you override OnCreate
instead:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
GeneratedPluginRegistrant.registerWith(this)
}
I hit this yesterday and just figured it out! This is not related to the plugin directly. For secure storage to work on Android I had to modify the
MainActivity.kt
file. (NOTE: from what I was reading, a lot of Flutter projects are using JAVA and the solution was slightly different but also in the MainActivity.java file)Instead of
MainActivity
extendingFlutterActivity
, I had to extend fromFlutterFragmentActivity
in order for Touch ID to work on Android. When I did this it broke the project but I normally work on iOS so I didn't notice. Flutter generates a class namedGeneratedPluginRegistrant.java
. If this doesn't get called then Flutter can't see the plugin and you get theMissingPluginException
.I believe
FlutterActivity
is calling the plugin registration for you (at least in newer versions of Flutter).FlutterFragmentActivity
doesn't make that call so you need to explicitly do it. Here is my newMainActivity.kt
that is working:import io.flutter.embedding.android.FlutterFragmentActivity import io.flutter.embedding.engine.FlutterEngine import io.flutter.plugins.GeneratedPluginRegistrant class MainActivity: FlutterFragmentActivity() { override fun configureFlutterEngine(flutterEngine: FlutterEngine) { super.configureFlutterEngine(flutterEngine) GeneratedPluginRegistrant.registerWith(flutterEngine) } }
If you have a MainActivity.java file, here is what I found online that I had to translate to Kotlin. Note that the only difference is you override
OnCreate
instead:override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) GeneratedPluginRegistrant.registerWith(this) }
that help thanks very thanks.
I now get this but every things work fine
E/dalvikvm( 2809): Could not find class 'android.security.keystore.KeyGenParameterSpec$Builder', referenced from method com.it_nomads.fluttersecurestorage.ciphers.RSACipher18Implementation.createKeys
W/dalvikvm( 2809): VFY: unable to resolve new-instance 254 (Landroid/security/keystore/KeyGenParameterSpec$Builder;) in Lcom/it_nomads/fluttersecurestorage/ciphers/RSACipher18Implementation;
D/dalvikvm( 2809): VFY: replacing opcode 0x22 at 0x007f
E/dalvikvm( 2809): Could not find class 'android.security.keystore.StrongBoxUnavailableException', referenced from method com.it_nomads.fluttersecurestorage.ciphers.RSACipher18Implementation.createKeys
W/dalvikvm( 2809): VFY: unable to resolve instanceof 256 (Landroid/security/keystore/StrongBoxUnavailableException;) in Lcom/it_nomads/fluttersecurestorage/ciphers/RSACipher18Implementation;
D/dalvikvm( 2809): VFY: replacing opcode 0x20 at 0x00fb
D/dalvikvm( 2809): DexOpt: unable to opt direct call 0x042e at 0x84 in Lcom/it_nomads/fluttersecurestorage/ciphers/RSACipher18Implementation;.createKeys
D/dalvikvm( 2809): DexOpt: unable to opt direct call 0x042e at 0x104 in Lcom/it_nomads/fluttersecurestorage/ciphers/RSACipher18Implementation;.createKeys
this for kotlin i get it from local_auth change MainActivity.kt
package com.[your.package]
import androidx.annotation.NonNull;
import io.flutter.embedding.android.FlutterFragmentActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugins.GeneratedPluginRegistrant
class MainActivity: FlutterFragmentActivity() {
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine);
}
}
also that work with 3.3.3 version
if need to replicate this error it is happens in emulator 4.4.4 all the time.
For me it happen on android 10, flutter 1.20.3.
@BrightChad solution doesn't work for me as I didn't change anything on the activity and PluginRegistrant call is already there.
still happening and reproducable. Real Device, Android 9, release Mode, Flutter 1.22.0
Way to reproduce it for me:
If i put the App to the Background, close it completly right after it and reopen it, the error its happening. It has something to do with, that the App is put in the Background for a while, then closed and reopened.
This Way to reproduce is not working with emulator.
Please try the new version 3.3.5. It fixed a bunch of android thread safety issues.
@koskimas still same error, but the solution from @BrightChad seems to work.
Hello, Same error on my side with the version "3.3.5". I can't create a simple unit test to store and get a simple value, I get this error:
"MissingPluginException(No implementation found for method write on channel plugins.it_nomads.com/flutter_secure_storage)"
Flutter (Channel stable, 1.22.4, on Mac OS X 10.15.7 19H2 darwin-x64, locale fr-FR)
@antoinepemeja I believe it's a different error, and actually not an error, as it's expected behavior. The plugin requires iOS or Android, that you don't have in unit test environment.
Try to use mocks for unit testing, see details in https://pub.dev/packages/mockito.
See here: https://flutter.dev/docs/development/packages-and-plugins/plugin-api-migration
This stuff happens for a lot of plugins right now - annoying AF.
So I ran into this issue and for an entire day I proceeded to try every single solution I found.
After quite a while I actually found out this issue was caused by another dependency: flutter_facebook_login: ^3.0.0
.
Temporarely removing this dependency would allow secure_storage
to work just fine.
I realized I did not setup the flutter_facebook_login
library properly as stated in their documentation, some stuff needed to be added in the AndroidManifest.xml. Once added, everything is back to normal.
I know I'm probably the only one here that ran into this specific issue but might be able to help someone.
Did anyone managed to run Android with flutter_secure_storage? If I change MainActivity.kt the app doesn't run at all.
So, this is a common issue. I ran into it unit testing flutter app.
Here is the error:
package:flutter/src/services/platform_channel.dart 157:7 MethodChannel._invokeMethod
MissingPluginException(No implementation found for method read on channel plugins.it_nomads.com/flutter_secure_storage)
Running the latest plugin:
flutter_secure_storage: ^3.3.5
Testing on physical device: OnePlus 8T
Here's the setup:
khalid@linux:~$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel master, 1.25.0-5.0.pre.90, on Linux, locale en_US.UTF-8)
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
[✓] Android Studio
[✓] VS Code (version 1.52.1)
[✓] Connected device (1 available)
• No issues found!
I still got this issue when ran the unit tests
@thongdinh it's expected behavior in Unit Tests as there is no mobile environment and no plugins are available. Please use mocks (e.g. mocking)
@jamesncl I think you observed and brought up a set of great points on code quality. As a generalist developer, I'm on board with your highlights of the code smells. I wish I had any expertise with Android development to be able to review this sections of code, but I am actually super new even to Flutter development.
Stumbling onto the same issue. What @szotp mentioned with removing all keys on first run, did work for me, but it's a terrible work around:
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
const String DEMO_SECRET_KEY = 'demo-secret';
class Secrets {
final _storage = FlutterSecureStorage();
Future<String> loadDemoSecret(bool isFirstTimeApplicationExecution) {
final buildReadFuture = () => _storage.read(key: DEMO_SECRET_KEY);
final buildDeleteAllFuture = () => _storage.deleteAll();
return (isFirstTimeApplicationExecution)
? buildDeleteAllFuture().then((_) => buildReadFuture())
: buildReadFuture();
}
Future<void> saveDemoSecret(String demoSecret) {
return _storage.write(key: DEMO_SECRET_KEY, value: demoSecret);
}
Future<void> deleteDemoSecret() {
return _storage.delete(key: DEMO_SECRET_KEY);
}
}
After few hours of surfing. Finally SOLVED for me. Here is what I found out.
If you are calling flutter_secure_storage
(or any packages) method in background service (as example, when you are using notification onBackgroundMessage
). This exception occurred because usually our plugin registered at main.dart
in foreground, but if we are calling our plugin's method in background we need to manually registered our plugin in our app/src/main/[kotlin/java]/.../Application.[java or kt]
.
Inside the Application.java or Application.kt
After done that, do flutter run
again. Hope it helps!
I see this too, on API 27 / Android 8.1, but not on API 29 / Android 10.0 after upgrading my setup to Android embedding V2.
However, before the MissingPluginException there is this:
StorageCipher initialization failed
which may be the root cause. Seems like the plugin process crashes after the init failure which the causes the exception mentioned above.
See also issue #175
After few hours of surfing. Finally SOLVED for me. Here is what I found out.
Can you please post your whole Application.java file @wilyanto ?
I don't have one, but do have a MainActivity.java file... Is that where I should put this code?
In my case I just had to set the minSdkVersion to 18 (as mentioned in the doc), do a "flutter clean" and my error disappeared. flutter_secure_storage: v3.3.5 flutter: v1.22.6
The problem I'm running into is trying to use flutter_secure_storage in the background on android, specifically during firebase push notification handlers. Works fine on iOS. I don't think the flutter_secure_storage plugin supports running in the background on android without additional configuration. I wouldn't mind this if there were some simple docs on how to configure it to run in the background.
I was able to get it fixed. For me it involved upgrading to v2 embedding as my project was generated before flutter 1.12. I followed this guide and it fixed everything.
https://github.com/flutter/flutter/wiki/Upgrading-pre-1.12-Android-projects
My problem is solved and I think it is a compatibility issue between plugins. I created a new project and added the plugins one by one. Arrived at the _flutter_barcode_scanner: ^1.0.2_ plugin the error appeared. So I just removed it and my app works fine with version 4.1.0 of flutter_secure_storage Hope this helps other people.
I still have problems with Android 5 and 6 with flutter_secure_storage: 4.2.0
Can everyone that is still facing this issue make sure they are using embedding V2 on their application? Also, please post the output of flutter doctor -v
and try it with the latest version of this plugin v4.2.1.
Can everyone that is still facing this issue make sure they are using embedding V2 on their application? Also, please post the output of
flutter doctor -v
and try it with the latest version of this plugin v4.2.1.
I'm using embedding V2 with fresh project install.
flutter doctor -v
[✓] Flutter (Channel stable, 2.2.3, on macOS 11.4 20F71 darwin-x64, locale en-US)
• Flutter version 2.2.3 at /Users/imac/development/flutter
• Framework revision f4abaa0735 (7 weeks ago), 2021-07-01 12:46:11 -0700
• Engine revision 241c87ad80
• Dart version 2.13.4
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
• Android SDK at /Users/imac/Library/Android/sdk
• Platform android-30, build-tools 30.0.2
• Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 11.0.10+0-b96-7281165)
• All Android licenses accepted.
[✓] Xcode - develop for iOS and macOS
• Xcode at /Applications/Xcode.app/Contents/Developer
• Xcode 12.5.1, Build version 12E507
• CocoaPods version 1.10.1
[✓] Chrome - develop for the web
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
[✓] Android Studio (version 2020.3)
• Android Studio at /Applications/Android Studio.app/Contents
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 11.0.10+0-b96-7281165)
[✓] Connected device (3 available)
• Redmi Note 8 (mobile) • 17eba2c2 • android-arm64 • Android 10 (API 29)
• moto g 7 plus (mobile) • ZY225G7TW3 • android-arm64 • Android 10 (API 29)
• Chrome (web) • chrome • web-javascript • Google Chrome 92.0.4515.131
• No issues found!
Felipes-iMac-2:myklick imac$ flutter doctor -v
[✓] Flutter (Channel stable, 2.2.3, on macOS 11.4 20F71 darwin-x64, locale en-US)
• Flutter version 2.2.3 at /Users/imac/development/flutter
• Framework revision f4abaa0735 (7 weeks ago), 2021-07-01 12:46:11 -0700
• Engine revision 241c87ad80
• Dart version 2.13.4
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
• Android SDK at /Users/imac/Library/Android/sdk
• Platform android-30, build-tools 30.0.2
• Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 11.0.10+0-b96-7281165)
• All Android licenses accepted.
[✓] Xcode - develop for iOS and macOS
• Xcode at /Applications/Xcode.app/Contents/Developer
• Xcode 12.5.1, Build version 12E507
• CocoaPods version 1.10.1
[✓] Chrome - develop for the web
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
[✓] Android Studio (version 2020.3)
• Android Studio at /Applications/Android Studio.app/Contents
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 11.0.10+0-b96-7281165)
[✓] Connected device (3 available)
• Redmi Note 8 (mobile) • 17eba2c2 • android-arm64 • Android 10 (API 29)
• moto g 7 plus (mobile) • ZY225G7TW3 • android-arm64 • Android 10 (API 29)
• Chrome (web) • chrome • web-javascript • Google Chrome 92.0.4515.131
• No issues found!
Any workaround?
Any update?
Can everyone that is still facing this issue make sure they are using embedding V2 on their application? Also, please post the output of
flutter doctor -v
and try it with the latest version of this plugin v4.2.1.I'm using embedding V2 with fresh project install.
flutter doctor -v [✓] Flutter (Channel stable, 2.2.3, on macOS 11.4 20F71 darwin-x64, locale en-US) • Flutter version 2.2.3 at /Users/imac/development/flutter • Framework revision f4abaa0735 (7 weeks ago), 2021-07-01 12:46:11 -0700 • Engine revision 241c87ad80 • Dart version 2.13.4 [✓] Android toolchain - develop for Android devices (Android SDK version 30.0.2) • Android SDK at /Users/imac/Library/Android/sdk • Platform android-30, build-tools 30.0.2 • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 11.0.10+0-b96-7281165) • All Android licenses accepted. [✓] Xcode - develop for iOS and macOS • Xcode at /Applications/Xcode.app/Contents/Developer • Xcode 12.5.1, Build version 12E507 • CocoaPods version 1.10.1 [✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome [✓] Android Studio (version 2020.3) • Android Studio at /Applications/Android Studio.app/Contents • Flutter plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/6351-dart • Java version OpenJDK Runtime Environment (build 11.0.10+0-b96-7281165) [✓] Connected device (3 available) • Redmi Note 8 (mobile) • 17eba2c2 • android-arm64 • Android 10 (API 29) • moto g 7 plus (mobile) • ZY225G7TW3 • android-arm64 • Android 10 (API 29) • Chrome (web) • chrome • web-javascript • Google Chrome 92.0.4515.131 • No issues found! Felipes-iMac-2:myklick imac$ flutter doctor -v [✓] Flutter (Channel stable, 2.2.3, on macOS 11.4 20F71 darwin-x64, locale en-US) • Flutter version 2.2.3 at /Users/imac/development/flutter • Framework revision f4abaa0735 (7 weeks ago), 2021-07-01 12:46:11 -0700 • Engine revision 241c87ad80 • Dart version 2.13.4 [✓] Android toolchain - develop for Android devices (Android SDK version 30.0.2) • Android SDK at /Users/imac/Library/Android/sdk • Platform android-30, build-tools 30.0.2 • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 11.0.10+0-b96-7281165) • All Android licenses accepted. [✓] Xcode - develop for iOS and macOS • Xcode at /Applications/Xcode.app/Contents/Developer • Xcode 12.5.1, Build version 12E507 • CocoaPods version 1.10.1 [✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome [✓] Android Studio (version 2020.3) • Android Studio at /Applications/Android Studio.app/Contents • Flutter plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/6351-dart • Java version OpenJDK Runtime Environment (build 11.0.10+0-b96-7281165) [✓] Connected device (3 available) • Redmi Note 8 (mobile) • 17eba2c2 • android-arm64 • Android 10 (API 29) • moto g 7 plus (mobile) • ZY225G7TW3 • android-arm64 • Android 10 (API 29) • Chrome (web) • chrome • web-javascript • Google Chrome 92.0.4515.131 • No issues found!
Same output, same problem
@juliansteenbakker any update?
I can't seem to reproduce this so i can't debug it. It seems like it happens alot on Redmi and Huawei devices. I don't have those devices so i'm hoping someone else who can reproduce this is able to find the problem.
I can't seem to reproduce this so i can't debug it. It seems like it happens alot on Redmi and Huawei devices. I don't have those devices so i'm hoping someone else who can reproduce this is able to find the problem.
I have a moto g7 plus, Poco x3 pro, in android emulator and nothing works
Do all these devices have access to Google Play API? And which version of this plugin are you using? I have tried with fresh install on emulator and it works just fine
Do all these devices have access to Google Play API? And which version of this plugin are you using? I have tried with fresh install on emulator and it works just fine
Moto g7 plus and Poco x3 pro are physical devices, they have Google play, i'm using flutter_secure_storage: ^4.2.1
I will try with other emulator maybe it don't have google play, i'll let you know
I just try with this emulator and keep crashing
I try Nexus 5x to ensure it's not a problem with Pixel emulators
and the same
Let me know if i can do to help with this
The plugin works fine in the same project but in ios
The plugin works fine in the same project but in ios
On a real device? Because it doesn't work on my iPhone emulator
The plugin works fine in the same project but in ios
On a real device? Because it doesn't work on my iPhone emulator
Physical device, Ipad Air with IOS 12.4.9
I need to publish an app in one week and i do not know what to do, any help?
After upgrade flutter to 2.5.0 works fine in android and emulators
@Rubensb @juliansteenbakker
Any news about this problem ?
I've got the same problem here. It seems to work on real device but not on an emulator (Pixel 5, API 27)
Flutter 2.5.1
same problem
There are currently all these open issues for flutter_secure_storage, all mention the exception
MissingPluginException(No implementation found for method read on channel plugins.it_nomads.com/flutter_secure_storage)
in the issue or in the comments:#5 - Sporadic finalizer exceptions for underlying KeyStore on Android #49 - MissingPluginException (MissingPluginException(No implementation found for method read on channel plugins.it_nomads.com/flutter_secure_storage)) #71 - MissingPluginException #83 - MissingPluginException(No implementation found for method write on channel plugins.it_nomads.com/flutter_secure_storage) #85 - doesn't work on api level 23 #118 - Android 4.4.2: MissingPluginException(No implementation found for method write on cannel plugins.it_nomads.com/flutter_secure_storage)) #129 - Not Working in android 5.1.1 and 4.4.4 #136 - Can't run flutter test due to MissingPluginException in flutter_secure_storage
I'm also experiencing this exception with my end users, but with 8 open issues it's difficult to have to a sensible conversation - can I suggest we use this one thread to resolve this?
Most suggested "solutions" are to uninstall / reinstall the app,
flutter clean
, etc. however this simply isn't a solution - you can't ask end users to reinstall your app.One suggestion I have is that based on the data below, it looks like this is an Android only problem - so perhaps there is a problem with how the plugin is registered on Android? The fact that it only happens sometimes, for some users, then occasionally it magically disappears, also suggests it is a timing issue.
Affected versions
After a quick survey of the issues, the exception has been reported on the following versions:
Affected devices
Some questions for flutter_secure_storage developers
To try to help, when looking through the code the following questions came to mind (I'm not a plugin developer so you may have to bear with me!)
Silently swallowing exceptions There are a couple of places where you catch Exceptions, but then just Log and do nothing else:
Could these be surfaced to flutter via an error Result instead of silently discarded? This might reveal where there are actual problems when encountered.
Use of volatile You're using
volatile
here:and link to a very long and complicated article on double-checked locking. Can you explain the reason behind using this instead of simply using an
AsyncTask
to perform work on a separate thread? If I had to bet money on why we getMissingPluginException
, this would be it - edge case race conditions caused by complex multi-threading code.Are you passing the right context? In
initInstance
you are doing this:Notice you are getting and assigning the application context first, but then passing the context from the parameter to the
moveSecretFromPreferencesIfNeeded
method - is that right? I have no idea if that's a problem, just thought I should ask the question.BinaryMessenger
It looks like you're getting a
BinaryMessenger
directly from the binding object here to give to theMethodChannel
:However the latest plugin template gets the
BinaryMessenger
via the flutter engine like this:Is that a problem do you think?
Setting method channel to null
onDetachedFromEngine
you're setting channel to null. Is this necessary? Might it not cause a problem ifchannel
is accessed after this is called? The latest plugin template doesn't do this, it just setschannel.setMethodCallHandler(null)
and nothing else.