每次我刷新应用程序时都会触发Flatter web Firebase onAuthStateChanges
我正在使用FlatterWeb开发一个web应用程序 每次我刷新页面时,都会触发onAuthStateChanges,并执行仅当auth状态发生更改时才应触发的函数 这种行为是故意的吗 为了订阅onAuthStateChanges,我用一个有状态的小部件包装了我的主小部件,并收听了onAuthStateChanges,如下所示: 以下是我的代码: 我的包装纸:每次我刷新应用程序时都会触发Flatter web Firebase onAuthStateChanges,firebase,flutter,firebase-authentication,flutter-web,Firebase,Flutter,Firebase Authentication,Flutter Web,我正在使用FlatterWeb开发一个web应用程序 每次我刷新页面时,都会触发onAuthStateChanges,并执行仅当auth状态发生更改时才应触发的函数 这种行为是故意的吗 为了订阅onAuthStateChanges,我用一个有状态的小部件包装了我的主小部件,并收听了onAuthStateChanges,如下所示: 以下是我的代码: 我的包装纸: /// Wrapper for stateful functionality to provide onInit calls in s
/// Wrapper for stateful functionality to provide onInit calls in stateles widget
class StatefulWrapper extends StatefulWidget {
final Function onInit;
final Widget child;
const StatefulWrapper({@required this.onInit, @required this.child});
@override
_StatefulWrapperState createState() => _StatefulWrapperState();
}
class _StatefulWrapperState extends State<StatefulWrapper> {
@override
void initState() {
if (widget.onInit != null) {
widget.onInit();
}
super.initState();
}
@override
Widget build(BuildContext context) {
return widget.child;
}
}
发生的情况是,当我在浏览器中刷新页面时,会触发此函数的侦听器,如果我没有登录,它会导航到登录,否则会导航到主页
这是有意的吗?对我来说,侦听器应该只在其侦听内容发生更改时启动。当应用程序加载时,Firebase会检查用户的身份验证状态。在该进程开始时,is调用任何具有空值的活动身份验证状态侦听器。如果可以对用户进行身份验证,那么它将使用用户配置文件对象调用侦听器
因此,您看到的内容确实可以正常工作。如果刷新页面,实际上就是重新启动整个应用程序。这是故意的,否则启动时无法获得身份验证状态。好吧,但为什么会触发函数的处理程序?对我来说,这没有任何意义。我的意思是,只有在该事件发生时,才应该尝试调用侦听器的处理程序。当我刷新时,我的登录状态没有改变,与以前一样。如果他们删除了这个,就无法确定应用程序启动时的身份验证状态。刷新网页时,它不会“记住”以前的身份验证状态。你正在重新启动整个应用程序。我还有一个问题。根据我在这里展示的代码,触发器似乎被触发了不止一次。我想某个地方应该有一个bug,因为这不是故意的,对吧?页面加载时,通常会使用
null
调用您的回调,然后在几分钟后与实际用户一起调用。谢谢您的解释。然而,我注意到一种与你揭露我的行为不同的行为。当我登录和注销时,侦听器只被调用一次。当我刷新页面时,会多次调用侦听器,但如果我登录,则会使用用户的值多次调用侦听器。而如果我没有登录,它会多次使用null调用。下面是刷新页面的示例:激发了侦听器-时间戳:2020-09-11 09:17:53.741电子邮件是:mail@mail.com已启动侦听器-时间戳:2020-09-11 09:17:53.755电子邮件为:mail@mail.comI我曾经在手机上使用过firebase,我很喜欢它,但这种在网络上的行为让我很为难。因为我需要保存我的用户身份验证状态,所以我想使用侦听器将他重定向到正确的页面。然而,侦听器多次调用,使得web应用程序有几个无用且恼人的重定向。解决这个问题的标准方法是什么?到目前为止,我在侦听器中没有任何重定向,但是我使用了一个共享首选项(loggedIn),并且我有一个启动屏幕来检查这个变量并相应地重定向到它。但我觉得这是一个解决方法,不是正确的方法。我发现的另一个解决方案是检查onAuthStateChange中的时间戳。如果时间戳大于500毫秒,则进行导航。但我仍然认为这是一个肮脏的解决办法,而不是一个解决方案。
Widget build(BuildContext context) {
var router = MyRouter.Router();
var authenticationService = locator<AuthenticationService>();
var sharedPreferences = locator<SharedPreferencesService>();
return StatefulWrapper(
onInit: () {
authenticationService.listenToAuthChanges();
},
child: FutureBuilder(
future: sharedPreferences.getSharedPreferences('ruolo'),
builder: (context, snapshot) {
return MaterialApp(
builder: ExtendedNavigator<MyRouter.Router>(
initialRoute: MyRouter.Routes.startupView,
guards: [AuthGuard(), AdminGuard()],
router: router,
navigatorKey: locator<NavigationService>().navigatorKey,
),
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
onGenerateRoute: router.onGenerateRoute,
);
}),
);
}
void listenToAuthChanges() {
FirebaseAuth.instance.authStateChanges().listen((firebaseUser) async {
if (firebaseUser == null) {
navigationService.navigateTo(Routes.login);
} else {
navigationService.replaceWith(Routes.home);
}
});
}