You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter入门:点击按钮后StreamBuilder无法重建UserSettingsPage问题

问题:StreamBuilder无法重建UserSettingsPage组件

我的组件树中,StreamBuilder(紫色) 负责根据Firebase auth状态切换页面,点击FloatingActionButton(红色) 触发登出操作后,应用会重建,但UserSettingsPage(绿色) 不在StreamBuilder的下级组件树中,因此不会被重建,我需要让它能随auth状态变化更新或重建。

我的初步思路:

  • 将StreamBuilder移到MaterialApp上方,但不知道具体实现方式
  • 将UserSettingsPage移到HomePage同级

解决方案

方案1:在UserSettingsPage中直接监听auth状态变化

通过监听FirebaseAuth的authStateChanges流,当用户登出时自动跳转到登录页,同时实时更新页面UI。

修改UserSettingsPage代码:

class UserSettingsPage extends StatefulWidget {
  const UserSettingsPage({Key? key}) : super(key: key);

  @override
  _UserSettingsPageState createState() => _UserSettingsPageState();
}

class _UserSettingsPageState extends State<UserSettingsPage> {
  late StreamSubscription<User?> _authSubscription;

  @override
  void initState() {
    super.initState();
    // 监听auth状态变化
    _authSubscription = FirebaseAuth.instance.authStateChanges().listen((user) {
      if (user == null) {
        // 登出后清空导航栈,跳转到登录页
        Navigator.of(context).pushAndRemoveUntil(
          MaterialPageRoute(builder: (context) => const LoginPage()),
          (route) => false,
        );
      }
    });
  }

  @override
  void dispose() {
    _authSubscription.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final provider = Provider.of<GoogleSignInProvider>(context);
    return Scaffold(
      body: ListView(
        children: [
          Text('登录状态:${provider.isLoggedWithGoogle() ? '已登录' : '已登出'}'),
          ElevatedButton(
            onPressed: () {
              final provider = Provider.of<GoogleSignInProvider>(context, listen: false);
              provider.logout();
            },
            child: const Text('退出登录'),
          ),
        ],
      ),
    );
  }
}

方案2:将StreamBuilder提升到MaterialApp外层

把StreamBuilder放在MaterialApp的外层,让整个应用都能响应auth状态变化,登出后直接切换到登录页。

修改main.dart代码:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => GoogleSignInProvider()),
        ChangeNotifierProvider(create: (_) => ThemesProvider()),
        ChangeNotifierProvider(create: (_) => ZmienneClass())
      ],
      child: const MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return StreamBuilder<User?>(
      stream: FirebaseAuth.instance.authStateChanges(),
      builder: (context, snapshot) {
        return MaterialApp(
          debugShowCheckedModeBanner: false,
          theme: Provider.of<ThemesProvider>(context).darkModeOn
              ? ThemeOptions.white
              : ThemeOptions.black,
          home: Scaffold(
            body: _buildAuthContent(snapshot),
          ),
        );
      },
    );
  }

  Widget _buildAuthContent(AsyncSnapshot<User?> snapshot) {
    if (snapshot.connectionState == ConnectionState.waiting) {
      return const Center(child: CircularProgressIndicator());
    } else if (snapshot.hasData) {
      return const HomePage();
    } else if (snapshot.hasError) {
      return const Center(child: Text("出现错误.."));
    } else {
      return const LoginPage();
    }
  }
}

额外修复:GoogleSignInProvider中的无效代码

原代码中logout方法里的isLoggedWithGoogle() == false;是无效语句,删除后修正:

class GoogleSignInProvider extends ChangeNotifier {
  bool isLoggedWithGoogle() {
    final provUser = FirebaseAuth.instance.currentUser;
    return provUser?.providerData[0].providerId == "google.com";
  }

  Future logout() async {
    final provUser = FirebaseAuth.instance.currentUser;
    if (provUser != null && provUser.providerData[0].providerId == "google.com") {
      await googleSignIn.disconnect();
    }
    await FirebaseAuth.instance.signOut();
    notifyListeners();
  }
}

内容的提问来源于stack exchange,提问作者Malak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 13:05:30