每次我刷新应用程序时都会触发Flatter web Firebase 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

我正在使用FlatterWeb开发一个web应用程序

每次我刷新页面时,都会触发onAuthStateChanges,并执行仅当auth状态发生更改时才应触发的函数

这种行为是故意的吗

为了订阅onAuthStateChanges,我用一个有状态的小部件包装了我的主小部件,并收听了onAuthStateChanges,如下所示:

以下是我的代码:

我的包装纸:

/// 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);
      }
    });
  }