Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"Null check operator used on null value" error on read #336

Closed
A-a-l-l-e-e-x-x opened this issue Nov 18, 2021 · 11 comments
Closed

"Null check operator used on null value" error on read #336

A-a-l-l-e-e-x-x opened this issue Nov 18, 2021 · 11 comments

Comments

@A-a-l-l-e-e-x-x
Copy link

A-a-l-l-e-e-x-x commented Nov 18, 2021

Using v5.0.2

When calling any kind of read function, whether read or readAll, dart throws the following error:

Null check operator used on a null value - stack:
#0 MethodChannel.binaryMessenger package:flutter/…/services/platform_channel.dart:121
#1 MethodChannel._invokeMethod package:flutter/…/services/platform_channel.dart:146
#2 MethodChannel.invokeMethod package:flutter/…/services/platform_channel.dart:329
#3 MethodChannelFlutterSecureStorage.readAll package:flutter_secure_storage_platform_interface/src/method_channel_flutter_secure_storage.dart:61
#4 FlutterSecureStorage.readAll package:flutter_secure_storage/flutter_secure_storage.dart:164

From the looks of the stacktrace, the issue seems to be deeper-seated within flutter, although I'm obviously quite unsure whether it is due to a true Flutter problem or a bug in the FlutterSecureStorage library.

I'm unfortunately not well-versed enough with the deeper machinations of how Flutter work, so I'm unable to provide a fix pull request.

@juliansteenbakker
Copy link
Owner

Can you please provide output of flutter doctor -v, and also which device and os version you're getting this error on.

@A-a-l-l-e-e-x-x
Copy link
Author

`PS ...> flutter doctor -v
[√] Flutter (Channel stable, 2.5.3, on Microsoft Windows [Version 10.0.19043.1348], locale en-US)
• Flutter version 2.5.3 at E:...\flutter\flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision 18116933e7 (5 weeks ago), 2021-10-15 10:46:35 -0700
• Engine revision d3ea636dc5
• Dart version 2.14.4

[√] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
• Android SDK at ...\AndroidSDK
• Platform android-31, build-tools 31.0.0
• Java binary at: ...\AndroidStudio\jre\bin\java
• Java version OpenJDK Runtime Environment (build 11.0.10+0-b96-7249189)
• All Android licenses accepted.

[√] Chrome - develop for the web
• Chrome at ...\Google\Chrome\Application\chrome.exe

[√] Android Studio (version 2020.3)
• Android Studio at ...\AndroidStudio
• 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-7249189)

[√] Connected device (3 available)
• sdk gphone x86 (mobile) • emulator-5554 • android-x86 • Android 11 (API 30) (emulator)

• No issues found!`

The flutter doctor output doesn't seem to be particularly verbose, even with the -v flag? The device/OS is the one listed above, the Android 11 x86 emulator.

I'm going to try to make a minimum reproducible project for the bug, I'll update if that works.

@hemandroid
Copy link

Secure storage is returning null while reading data.

I'm testing the behavior on the iOS simulator, but it's not working.

Here is the response for flutter doctor -v

Hemas-MacBook-Pro:ios hemandroid$ flutter doctor -v
[✓] Flutter (Channel stable, 2.5.1, on macOS 11.6 20G165 darwin-x64, locale en-GB)
• Flutter version 2.5.1 at /Users/hemandroid/flutter_sdk/flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision ffb2ecea52 (9 weeks ago), 2021-09-17 15:26:33 -0400
• Engine revision b3af521a05
• Dart version 2.14.2

[✓] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
• Android SDK at /Users/hemandroid/Library/Android/sdk
• Platform android-31, build-tools 31.0.0
• Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 11.0.8+10-b944.6916264)
• All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS
• Xcode at /Applications/Xcode.app/Contents/Developer
• Xcode 13.1, Build version 13A1030d
• CocoaPods version 1.11.2

[✓] Chrome - develop for the web
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 4.2)
• 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.8+10-b944.6916264)

[✓] IntelliJ IDEA Community Edition (version 2019.3)
• IntelliJ at /Applications/IntelliJ IDEA CE.app
• Flutter plugin version 45.1.2
• Dart plugin version 193.7547

[✓] VS Code (version 1.61.2)
• VS Code at /Users/hemandroid/Softwares/Visual Studio Code.app/Contents
• Flutter extension version 3.27.0

[✓] Connected device (3 available)
• iPhone 11 (mobile) • B3CC329F-A9A3-4BC8-B6E9-21F05F585BAC • ios •
com.apple.CoreSimulator.SimRuntime.iOS-15-0 (simulator)
• macOS (desktop) • macos • darwin-x64 • macOS 11.6 20G165 darwin-x64
• Chrome (web) • chrome • web-javascript • Google Chrome 95.0.4638.69

• No issues found!

Log Response:

Null check operator used on a null value

@juliansteenbakker
Copy link
Owner

So it seems this is happening on Android and iOS. @A-a-l-l-e-e-x-x Do you have an update on the sample project? I can't seem to reproduce this myself.

@heavenboy8
Copy link

heavenboy8 commented Nov 23, 2021

Hello,

I have exactly the same issue than @A-a-l-l-e-e-x-x on 5.0.2. I'm very interested by any suggestions. I'm quite stuck for now.
For now, I'm just running a simple test in AndroidStudio (running on Ubuntu):

const FlutterSecureStorage storage = FlutterSecureStorage();
await storage.write(key: 'access_token', value: tokens['access_token']);

and:

package:flutter/src/services/platform_channel.dart 121:86         MethodChannel.binaryMessenger
package:flutter/src/services/platform_channel.dart 146:36         MethodChannel._invokeMethod
package:flutter/src/services/platform_channel.dart 329:12         MethodChannel.invokeMethod
package:flutter_secure_storage/flutter_secure_storage.dart 30:22  FlutterSecureStorage.write
test/services/service_user_test.dart 25:17                        main

Thanks

@juliansteenbakker
Copy link
Owner

Can you please try the following:

You'll likely have to call WidgetsFlutterBinding.ensureInitialized() in your main before you do anything with the MethodChannel. Usually runApp calls this for you, but if you have logic before runApp that depends on the framework you'll have to call it yourself. The error message could definitely be better here.

Source: flutter/flutter#80956 (comment)

@tfreebern2
Copy link

tfreebern2 commented Nov 23, 2021

I believe it was related to the 2.5.3 upgrade. All of my tests relying on MethodChannel mocking are failing and I've started the migration process.

https://docs.flutter.dev/release/breaking-changes/mock-platform-channels

However, for Secure Storage I'm getting null when the test attempts to read.

TestDefaultBinaryMessengerBinding.instance?.defaultBinaryMessenger
      .setMockMethodCallHandler(MethodChannel('plugins.it_nomads.com/flutter_secure_storage'), (MethodCall methodCall) {
    if (methodCall.method == 'read') {
      return Future.value(encrypt);
    }
    return null;
  });

Null check operator used on a null value

I've also had to use TestWidgetsFlutterBinding.ensureInitialized(); in my main() function.

Other tests that are using different plugins are not having this issue when migrating to this new code.

EDIT:

I found my issue. I forgot to stub out the containsKey method.

    if (methodCall.method == 'containsKey') {
      return Future.value(true);
    }

@heavenboy8
Copy link

@juliansteenbakker your suggestion looks good. I have another issue from now. I didn't investigate a lot but I copy it here:

MissingPluginException(No implementation found for method write on channel plugins.it_nomads.com/flutter_secure_storage)

I guess this is due to the fact that we can't test a function having flutter_secure_storage dependencies but I need to mock the flutter_secure_storage calls instead. Right?

@tfreebern2
Copy link

@juliansteenbakker your suggestion looks good. I have another issue from now. I didn't investigate a lot but I copy it here:

MissingPluginException(No implementation found for method write on channel plugins.it_nomads.com/flutter_secure_storage)

I guess this is due to the fact that we can't test a function having flutter_secure_storage dependencies but I need to mock the flutter_secure_storage calls instead. Right?

So this is a quick example of how I got it worked for me in my Tests.

void main() {
    TestWidgetsFlutterBinding.ensureInitialized();
    
        TestDefaultBinaryMessengerBinding.instance?.defaultBinaryMessenger
        .setMockMethodCallHandler(const MethodChannel('plugins.it_nomads.com/flutter_secure_storage'), (MethodCall methodCall) {
      if (methodCall.method == 'read') {
        return Future.value('7890');
      }
      if (methodCall.method == 'write') {
        return null;
      }
      if (methodCall.method == 'delete') {
        return null;
      }
      if (methodCall.method == 'containsKey') {
        return Future.value(true);
      }
      return null;
    });
    
    ... rest of file ...
}

@heavenboy8
Copy link

heavenboy8 commented Nov 24, 2021

I would like to thank you. It works. I really appreciate your support.

Reading your example, I noticed that I used WidgetsFlutterBinding.ensureInitialized(); instead of TestWidgetsFlutterBinding.ensureInitialized(). It caused my last issue. Your piece of code is then perfect.

For info, using TestWidgetsFlutterBinding.ensureInitialized() makes all my tests on failure with the following error:

Warning: At least one test in this suite creates an HttpClient. When
running a test suite that uses TestWidgetsFlutterBinding, all HTTP
requests will return status code 400, and no network request will
actually be made. Any test expecting a real network connection and
status code will fail.
To test code that needs an HttpClient, provide your own HttpClient
implementation to the code under test, so that your test can
consistently provide a testable response to the code under test.

However, adding HttpOverrides.global = null; reactivates the default network behavior and makes all my tests working fine.

Cheers.

@juliansteenbakker
Copy link
Owner

I've added a note in the readme.md.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants