红色错误屏幕的瞬间闪烁 - Getter UID 在 NULL 上调用
Momentary Flash of Red Error Screen - Getter UID Called on NULL
我正准备部署我的第一个应用程序版本 - 但在我上线之前我被困在最后一个项目上,并且真的需要一些帮助。我想我知道为什么会这样,但不知道如何解决。
当我第一次从设备打开应用程序时,在屏幕正确加载和应用程序加载(登录屏幕)之前我看到红色错误屏幕几分之一秒,运行一切正常.只有当用户未登录时才会发生这种情况。如果他们已登录,则 运行 没问题。
打开应用程序时 - main.dart 检查用户是否已登录。如果他们没有登录,它会将他们发送到登录屏幕(通过 Navigator.push)。 main.dart 的其余部分假定用户已登录,并将 运行 基于 uid 进行查询。
我认为发生的事情是 main.dart 文件试图在重定向到登录页面开始之前完整加载。因此看到其余脚本调用 uid - 当然它在哪里为空。
我的假设(可能不正确)是 运行 的第一个脚本是下面的 getCurrentUser,用于检查用户登录状态。所以我 'thought' 应用程序会到达那里并在屏幕的其余部分加载之前让用户离开。
不是这样吗 - 有什么方法可以让这个脚本 'wait' 运行 并完成,然后在需要时让用户登录吗?
void getCurrentUser() async {
try {
final user = _auth.currentUser;
if (user == null) {
navigateToSubPageMyLoginScreen(context);
print('You are not logged in');
} else if (user != null) {
if (user.emailVerified == false) {
navigateToSubPageValideMe(context);
print('You are not verified');
} else {
print('All Good');
}
}
} catch (e) {
print(e);
}
}
提前致谢!
期望的行为是应用程序加载时不会出现红色屏幕显示错误“Getter 'UID' is null”
出于明显的用户体验原因,不鼓励在可能“挂起”应用程序的 async
方法中单独使用 await
语句。
您可以使用类似下面的内容在您的应用首次加载用户数据时提供一个基本的等待屏幕,然后根据结果导航到适当的页面。
class LoginChecker extends StatefulWidget {
@override
_LoginCheckerState createState() => _LoginCheckerState();
}
class _LoginCheckerState extends State<LoginChecker> {
@override
void initState() {
super.initState();
checkLogin();
}
Future<void> checkLogin() async {
// ↓ Example fake loading delay while you grab slow loading resources
User user = await Future.delayed(Duration(seconds: 2), () => User());
if (user == null)
Navigator.push(context, MaterialPageRoute(builder: (context) => MyLoginScreen()));
else
Navigator.push(context, MaterialPageRoute(builder: (context) => UserHome()));
}
@override
Widget build(BuildContext context) {
return Text('loading user info...');
}
}
class MyLoginScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(child: Text('Login here')),
);
}
}
class UserHome extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(child: Text('user home page'),),
);
}
}
/* Don't use this if you have firebase_auth importing user.dart which defines a User class.
class User {
String name;
}*/
在 checkLogin()
方法中,await
语句不会阻止 LoginChecker
页面加载,因为 initState
不是等待的异步方法阻止事件循环。
await
仅 pauses/waits 用于在本地异步外壳中处理。
Flutter 团队video explaining futures 做得很好。
如果您想要更深入的细节,可以使用 in-depth explanation of the way Flutter/Dart processes statements in its event loop。
我正准备部署我的第一个应用程序版本 - 但在我上线之前我被困在最后一个项目上,并且真的需要一些帮助。我想我知道为什么会这样,但不知道如何解决。
当我第一次从设备打开应用程序时,在屏幕正确加载和应用程序加载(登录屏幕)之前我看到红色错误屏幕几分之一秒,运行一切正常.只有当用户未登录时才会发生这种情况。如果他们已登录,则 运行 没问题。
打开应用程序时 - main.dart 检查用户是否已登录。如果他们没有登录,它会将他们发送到登录屏幕(通过 Navigator.push)。 main.dart 的其余部分假定用户已登录,并将 运行 基于 uid 进行查询。
我认为发生的事情是 main.dart 文件试图在重定向到登录页面开始之前完整加载。因此看到其余脚本调用 uid - 当然它在哪里为空。
我的假设(可能不正确)是 运行 的第一个脚本是下面的 getCurrentUser,用于检查用户登录状态。所以我 'thought' 应用程序会到达那里并在屏幕的其余部分加载之前让用户离开。
不是这样吗 - 有什么方法可以让这个脚本 'wait' 运行 并完成,然后在需要时让用户登录吗?
void getCurrentUser() async {
try {
final user = _auth.currentUser;
if (user == null) {
navigateToSubPageMyLoginScreen(context);
print('You are not logged in');
} else if (user != null) {
if (user.emailVerified == false) {
navigateToSubPageValideMe(context);
print('You are not verified');
} else {
print('All Good');
}
}
} catch (e) {
print(e);
}
}
提前致谢!
期望的行为是应用程序加载时不会出现红色屏幕显示错误“Getter 'UID' is null”
出于明显的用户体验原因,不鼓励在可能“挂起”应用程序的 async
方法中单独使用 await
语句。
您可以使用类似下面的内容在您的应用首次加载用户数据时提供一个基本的等待屏幕,然后根据结果导航到适当的页面。
class LoginChecker extends StatefulWidget {
@override
_LoginCheckerState createState() => _LoginCheckerState();
}
class _LoginCheckerState extends State<LoginChecker> {
@override
void initState() {
super.initState();
checkLogin();
}
Future<void> checkLogin() async {
// ↓ Example fake loading delay while you grab slow loading resources
User user = await Future.delayed(Duration(seconds: 2), () => User());
if (user == null)
Navigator.push(context, MaterialPageRoute(builder: (context) => MyLoginScreen()));
else
Navigator.push(context, MaterialPageRoute(builder: (context) => UserHome()));
}
@override
Widget build(BuildContext context) {
return Text('loading user info...');
}
}
class MyLoginScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(child: Text('Login here')),
);
}
}
class UserHome extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(child: Text('user home page'),),
);
}
}
/* Don't use this if you have firebase_auth importing user.dart which defines a User class.
class User {
String name;
}*/
在 checkLogin()
方法中,await
语句不会阻止 LoginChecker
页面加载,因为 initState
不是等待的异步方法阻止事件循环。
await
仅 pauses/waits 用于在本地异步外壳中处理。
Flutter 团队video explaining futures 做得很好。
如果您想要更深入的细节,可以使用 in-depth explanation of the way Flutter/Dart processes statements in its event loop。