【问题标题】:How am I supposed to use FirebaseAuth.instance.onAuthStateChanged in my flutter app?我应该如何在我的颤振应用程序中使用 FirebaseAuth.instance.onAuthStateChanged?
【发布时间】:2020-06-20 02:19:58
【问题描述】:

在我的颤振应用程序中,我试图通过使用 Provider 包中的 ChangeNotifier 将 Firebase 用户对象传递给下降的小部件。我的第一个想法是在 StreamBuilder 中这样做:

  Widget _authBuilder(context, Widget body) {
    final authModel = Provider.of<FAAuthModel>(context);


    return StreamBuilder(
      stream: FirebaseAuth.instance.onAuthStateChanged,
      builder: (context, snapshot) {

        authModel.user = snapshot.data;

        return body;
      },
    );
  }

唯一的问题是,显然构建器函数在构建主体小部件时异步运行,因此状态同时被标记为脏。有没有更聪明的方法将 FirebaseUser 传递给降序的小部件树?

I/flutter (28504): ══╡ EXCEPTION CAUGHT BY FOUNDATION LIBRARY ╞════════════════════════════════════════════════════════
I/flutter (28504): The following assertion was thrown while dispatching notifications for FAAuthModel:
I/flutter (28504): setState() or markNeedsBuild() called during build.
I/flutter (28504): This _DefaultInheritedProviderScope<FAAuthModel> widget cannot be marked as needing to build because
I/flutter (28504): the framework is already in the process of building widgets.  A widget can be marked as needing to
I/flutter (28504): be built during the build phase only if one of its ancestors is currently building. This exception
I/flutter (28504): is allowed because the framework builds parent widgets before children, which means a dirty
I/flutter (28504): descendant will always be built. Otherwise, the framework might not visit this widget during this
I/flutter (28504): build phase.
I/flutter (28504): The widget on which setState() or markNeedsBuild() was called was:
I/flutter (28504):   _DefaultInheritedProviderScope<FAAuthModel>
I/flutter (28504): The widget which was currently being built when the offending call was made was:
I/flutter (28504):   StreamBuilder<FirebaseUser>
I/flutter (28504): 

【问题讨论】:

    标签: firebase flutter dart firebase-authentication flutter-provider


    【解决方案1】:

    所以这个问题的答案是你不应该使用 StreamBuilder 而应该使用监听器..

      Widget _authBuilder(context, Widget body) {
        Stream<FirebaseUser> stream;
        final authModel = Provider.of<FAAuthModel>(context);
    
        stream = FirebaseAuth.instance.onAuthStateChanged;
    
        stream.listen((snapshot) {
    
          /* We are not logged in */
          if (snapshot == null && authModel.user == null) {
             //Do nothing
          }
          /* We are not logged in, or we are logging out */
          else if (snapshot == null) {
            authModel.user = null;
            /* We are logged in but we just opened our app */
          } else if (authModel.user == null) {
            authModel.user = snapshot;
            /* We are logged in but something happened e.g. the widget tree was rebuilt and we just logged out? */
          } else if (authModel.user.uid != snapshot.uid) {
            authModel.user = snapshot;
          }
        });
    
        return body;
      }
    
    

    【讨论】:

    • 使用 StreamBuilder 和监听器有什么不同吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-28
    • 2021-08-13
    • 2018-11-07
    • 2021-01-04
    • 1970-01-01
    • 1970-01-01
    • 2019-12-17
    相关资源
    最近更新 更多