【发布时间】:2021-12-31 11:11:04
【问题描述】:
我正在尝试制作一个包含登录屏幕和主屏幕(目前只有两个屏幕)的 Flutter 应用程序。我也在使用 Flutter Secure Storage 和 Http 库。
每当应用程序启动时,我希望应用程序检查两个道具 accessKey 和 accessId 是否存储在安全存储中。如果没有找到 accessId,它会自动生成并分配给 Uuid 库。而 accessKey 不是本地生成的,而是由 API 提供的。
应用导航到:
1)。 主屏幕,如果 accessKey 存储在 Secure Storage 中并且身份验证成功。
2)。 SignInScreen,如果未找到 accessKey 或身份验证失败。
我的问题是,每次我执行读取操作时,安全存储都会抛出错误“Null check operator used on a null value”。我已经初始化了存储变量,但是这个问题一直在发生。
这是我的安全存储类代码:
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
class FAS {
static FlutterSecureStorage? _storage;
static void init() {
_storage = const FlutterSecureStorage(
aOptions: AndroidOptions(encryptedSharedPreferences: true),
);
}
static Future<String?> read(String key) async {
return _storage!.read(key: key);
}
static Future<Map<String, String>> readAll() async {
return _storage!.readAll();
}
static Future<void> write(String key, String value) async {
await _storage!.write(key: key, value: value);
}
static Future<void> delete(String key) async {
await _storage!.delete(key: key);
}
static Future<void> deleteAll() async {
await _storage!.deleteAll();
}
}
之前,那段代码是这样的:
static const FlutterSecureStorage _storage = FlutterSecureStorage(aOptions: AndroidOptions(encryptedSharedPreferences: true));
没有初始化方法。
但我不断收到同样的错误。
这是我的 main.dart:
import 'package:flutter/material.dart';
import 'package:unified_bot_app/pages/home_page.dart';
import 'package:uuid/uuid.dart';
import './models/fas.dart';
import './pages/sign_in_page.dart';
import './request_methods.dart';
Future<void> tryAssignAccessId() async {
String? accessId = await FAS.read("ACCESS_ID");
if (accessId == null) {
await FAS.write("ACCESS_ID", (const Uuid()).v4());
}
}
void main() {
FAS.init();
tryAssignAccessId(); // <- Error
runApp(
MaterialApp(
home: FutureBuilder<bool>(
builder: (ctx, a) {
if (a.connectionState == ConnectionState.done) {
if (a.data!) return HomePage();
return const SignInPage();
}
return const Center(child: CircularProgressIndicator());
},
future: () async {
try {
String? accessKey = await FAS.read("ACCESS_KEY");
if (accessKey == null) {
return false;
}
return await HTTP.authenticate(accessKey);
} catch (e) {
return false;
}
}(),
),
theme: ThemeData(fontFamily: "Josefin Sans"),
),
);
}
这是我重新启动应用程序时得到的输出:
在 531 毫秒内重新启动应用程序。 E/颤振 (20760):
[错误:flutter/lib/ui/ui_dart_state.cc(209)] 未处理的异常:空
用于空值 E/flutter (20760) 的检查运算符:#0
MethodChannel.binaryMessenger
包:flutter/…/services/platform_channel.dart:121 E/flutter
(20760): #1 MethodChannel._invokeMethod
包:flutter/…/services/platform_channel.dart:146 E/flutter
(20760): #2 MethodChannel.invokeMethod
包:flutter/…/services/platform_channel.dart:329 E/flutter
(20760):#3 MethodChannelFlutterSecureStorage.read
包:flutter_secure_storage_platform_interface/src/method_channel_flutter_secure_storage.dart:49
E/flutter (20760):#4 FlutterSecureStorage.read
包:flutter_secure_storage/flutter_secure_storage.dart:91
E/颤振 (20760):#5 FAS.read
包:unified_bot_app/models/fas.dart:13 E/flutter (20760): #6
tryAssignAccessId 包:unified_bot_app/main.dart:10 E/flutter
(20760):#7 主包:unified_bot_app/main.dart:18 E/flutter
(20760): #8 _runMainZoned..
(dart:ui/hooks.dart:145:25) E/flutter (20760): #9 _rootRun
(dart:async/zone.dart:1428:13) E/flutter (20760): #10
_CustomZone.run (dart:async/zone.dart:1328:19) E/flutter (20760): #11 _runZoned (dart:async/zone.dart:1863:10) E/flutter (20760): #12 runZonedGuarded ( dart:async/zone.dart:1851:12) E/flutter (20760): #13
_runMainZoned。 (dart:ui/hooks.dart:141:5) E/flutter (20760): #14 _delayEntrypointInvocation.
(dart:isolate-patch/isolate_patch.dart:283:19) E/flutter (20760): #15
_RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12) E/flutter (20760):
D/EGL_emulation(20760): app_time_stats: avg=14143.50ms min=14143.50ms
max=14143.50ms 计数=1
但是,当我将前两行放在最后时(在 runApp(..) 之后),错误消失了:
void main() {
runApp(
MaterialApp(
home: FutureBuilder<bool>(
builder: (ctx, a) {
if (a.connectionState == ConnectionState.done) {
if (a.data!) return HomePage();
return const SignInPage();
}
return const Center(child: CircularProgressIndicator());
},
future: () async {
try {
String? accessKey = await FAS.read("ACCESS_KEY"); // <- Error re-appears here
if (accessKey == null) {
return false;
}
return await HTTP.authenticate(accessKey);
} catch (e) {
return false;
}
}(),
),
theme: ThemeData(fontFamily: "Josefin Sans"),
),
);
FAS.init();
tryAssignAccessId();
}
但是这样做,错误会重新出现在标记的行上。
我很困惑。发生了什么? 任何帮助表示赞赏。
编辑 1:
我在调用第二个 read() 方法之前尝试调用 init() 方法,但还是抛出了同样的错误。
更新部分:
future: () async {
try {
FAS.init();
String? accessKey = await FAS.read("ACCESS_KEY");
if (accessKey == null) {
return false;
}
return await HTTP.authenticate(accessKey);
} catch (e) {
print(e);
return false;
}
}(),
控制台输出:
在 510 毫秒内重新启动应用程序。 I/flutter (20760):空检查运算符
用于空值 D/EGL_emulation(20760):app_time_stats:
avg=1899.03ms min=1899.03ms max=1899.03ms count=1
【问题讨论】:
-
什么是
FAS.init();?是async吗? -
并尝试使用空字符串而不是 null,如下所示:
String accessKey = await FAS.read("ACCESS_KEY")??""; -
@ישואוהבאותך 没有 FAS.init() 不是异步的
-
@ישואוהבאותך 我也试过了,但即使安全存储中存在 ACCESS_KEY,它仍然返回空白字符串。
标签: flutter dart flutter-futurebuilder