Firebase authChanges 触发两次

问题描述 投票:0回答:1

class MyApp extends StatefulWidget {
  const MyApp({super.key});
  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  late Stream<fb_auth.User?> authChanges;

  @override
  void initState() {
    authChanges = fb_auth.FirebaseAuth.instance.authStateChanges();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        FocusScopeNode currentFocus = FocusScope.of(context);
        if (!currentFocus.hasPrimaryFocus &&
            currentFocus.focusedChild != null) {
          FocusManager.instance.primaryFocus!.unfocus();
        }
      },
      child: Consumer<ThemeProvider>(builder: (context, provider, _) {
        return MaterialApp(
          debugShowCheckedModeBanner: kDebugMode ? true : false,
          title: 'MY app',
          themeMode: provider.themeMode,
          home: StreamBuilder<fb_auth.User?>(
            stream: authChanges,
            builder: (BuildContext ctx,
                AsyncSnapshot<fb_auth.User?> firebaseAuthSnapshot) {
              final user = firebaseAuthSnapshot.data;
              if (ConnectionState.active ==
                  firebaseAuthSnapshot.connectionState) {
                return Consumer<RemoteConfigProvider>(
                  builder: (context, provider, _) {
                    if (user == null) {
                      return Login();
                    } else {
                      return BottomNavBar();
                    }
                  },
                );
              } else {
                return Center(
                  child: Spinner(),
                );
              }
            },
          ),
        );
      }),
    );
  }
}



这是我的实现,我正在努力理解我做错了什么。我在

StatefulWidget
中声明了我的流,并在
init
方法中设置了它。然而,我的
streamBuilder
被调用了两次,因此多次渲染子部件。

任何想法将不胜感激!

flutter firebase dart firebase-authentication
1个回答
0
投票

从您的代码中,我怀疑当“Consumer with ThemeProvider”由于通知更改而变脏并重建时,会发生对流的多次触发。

我建议将 ThemeProvider 消费者和流分开。

class MyApp extends StatefulWidget {
  const MyApp({super.key});
  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  late Stream<fb_auth.User?> authChanges;

  @override
  void initState() {
    authChanges = fb_auth.FirebaseAuth.instance.authStateChanges();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        FocusScopeNode currentFocus = FocusScope.of(context);
        if (!currentFocus.hasPrimaryFocus && currentFocus.focusedChild != null) {
          FocusManager.instance.primaryFocus!.unfocus();
        }
      },
      child: Consumer<ThemeProvider>(
        builder: (context, provider, _) {
          return MaterialApp(
            debugShowCheckedModeBanner: kDebugMode ? true : false,
            title: 'MY app',
            themeMode: provider.themeMode,
            home: AuthBasedWidget(authChanges: authChanges),
          );
        },
      ),
    );
  }
}

class AuthBasedWidget extends StatelessWidget {
  final Stream<fb_auth.User?> authChanges;
  
  const AuthBasedWidget({required this.authChanges});

  @override
  Widget build(BuildContext context) {
    return StreamBuilder<fb_auth.User?>(
      stream: authChanges,
      builder: (BuildContext ctx, AsyncSnapshot<fb_auth.User?> firebaseAuthSnapshot) {
        final user = firebaseAuthSnapshot.data;
        if (firebaseAuthSnapshot.connectionState == ConnectionState.active) {
          return Consumer<RemoteConfigProvider>(
            builder: (context, provider, _) {
              if (user == null) {
                return Login();
              } else {
                return BottomNavBar();
              }
            },
          );
        } else {
          return Center(
            child: Spinner(),
          );
        }
      },
    );
  }
}
最新问题
© www.soinside.com 2019 - 2024. All rights reserved.