我在应用程序中使用 Provider 和流 FirebaseAuth.instance.onAuthStateChanged 来决定在启动时重定向的位置,但是尽管用户已经登录(从上一次启动),但应用程序在登录屏幕上启动,大约 1 秒后重定向到主页,它应该从第一刻开始。即使在飞行模式下也会发生这种情况。
我想知道是否有任何方法可以解决此问题,即使无法立即显示主屏幕,我也不知道如何区分未登录的用户(空-> 登录屏幕)和加载用户(空-> 加载屏幕)。
部分代码:
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
final FirebaseAuth _auth = FirebaseAuth.instance;
final DatabaseService db = DatabaseService();
@override
Widget build(BuildContext context) {
return StreamProvider<FirebaseUser>.value(
value: _auth.onAuthStateChanged,
child: Consumer<FirebaseUser>(
builder: (context, firebaseUser, child) {
return MultiProvider(
providers: [
if (firebaseUser != null)
ChangeNotifierProvider(create: (ctx) => CollectionState(firebaseUser)),
StreamProvider<List<Collection>>.value(value: db.streamCollections(firebaseUser)),
],
child: MaterialApp(
title: 'My App',
routes: {
'/': (ctx) => LandingPage(),
'/login': (ctx) => LoginPage(),
'/emailSignIn': (ctx) => EmailSignInPage(),
'/emailSignUp': (ctx) => EmailSignUpPage(),
'/emailUnverified': (ctx) => EmailUnverifiedPage(),
'/home': (ctx) => HomePage(),
'/settings': (ctx) => Settings(),
},
),
);
},
),
);
}
}
class LandingPage extends StatelessWidget {
final DatabaseService _db = DatabaseService();
@override
Widget build(BuildContext context) {
final user = Provider.of<FirebaseUser>(context);
final userCondition =
user == null ? 'null' : user.isEmailVerified ? 'verifiedUser' : 'unverifiedUser';
switch (userCondition) {
case 'null':
return LoginPage();
break;
case 'unverifiedUser':
return EmailUnverifiedPage();
break;
case 'verifiedUser':
return HomePage();
break;
}
}
}
代码有点简化,我改为使用身份验证实例服务,仅此而已。
最佳答案
我知道我已经很晚了,但我已经遇到了同样的问题好几个星期了,我终于想通了。
@ChinkySight 说最好使用 StreamBuilder
是对的,主要是因为您可以访问 connectionState 属性。
存在滞后的原因是没有完全建立到流的连接。因此,在 ConnectionState.waiting 期间,返回一个小部件,如启动画面或只是一个容器。
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
return StreamBuilder(
stream: FirebaseAuth.instance.onAuthStateChanged,
builder: (_, snapshot) {
// Added this line
if (snapshot.connectionState == ConnectionState.waiting) {
return Container();
}
if (snapshot.data is FirebaseUser && snapshot.data != null) {
return HomePage();
}
return LoginPage();
});
}
}
您甚至可以使用 Animated Switcher 为您的返回语句添加精美的动画
return StreamBuilder(
stream: FirebaseAuth.instance.onAuthStateChanged,
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
Widget widget;
if (snapshot.connectionState == ConnectionState.waiting) {
return Container();
}
switch (snapshot.hasData) {
case (true):
widget = HomePage();
break;
case (false):
widget = LoginPage();
}
return Stack(
children: <Widget>[
Scaffold(
backgroundColor: Colors.grey.shade200,
),
AnimatedSwitcher(
duration: Duration(milliseconds: 700),
child: FadeTransition(
opacity: animation,
child: widget,
),
);
},
)
],
);
},
);
关于Flutter Firebase 身份验证 : delay on startup,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60760822/