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

Flutter桌面应用登录状态切换报错:Bad state: Stream has already been listened to

Flutter桌面应用firedart登录状态监听重复报错解决

问题描述

开发基于Firebase的Flutter桌面应用,使用firedart包实现登录逻辑,登录功能正常,但根据登录状态自动切换页面时,每次重新加载FirstPage都会触发错误:Bad state: Stream has already been listened to。

问题原因

firedart的FirebaseAuth.instance.signInState是单订阅流,这种流只能被监听一次。当前代码中MyHomePage的build方法每次重建都会创建新的StreamBuilder并监听该流,导致重复订阅触发错误。

解决方案

将单订阅流转换为多订阅流(Broadcast Stream),允许多次监听。在State的initState中初始化广播流,确保只转换一次,避免重复操作。

修改后的main.dart代码

import 'package:ame/screens/firstPage.dart';
import 'package:ame/screens/loginPage.dart';
import 'package:bitsdojo_window/bitsdojo_window.dart';
import 'package:firedart/auth/firebase_auth.dart';
import 'package:firedart/auth/token_store.dart';
import 'package:firedart/firestore/firestore.dart';
import 'package:flutter/material.dart';
import 'package:flutter_acrylic/flutter_acrylic.dart';
import 'package:google_fonts/google_fonts.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Window.initialize();
  await Window.setEffect(
    effect: WindowEffect.aero,
    color: const Color.fromARGB(50, 0, 0, 0),
  );

  FirebaseAuth.initialize(
      "AIzaSyBk76lyEHpyDgMot7csMmDiIKnPS_5QiYE", VolatileStore());

  var auth = FirebaseAuth.instance;

  runApp(const MyApp());
  doWhenWindowReady(() {
    var initialSize = const Size(600, 450);
    appWindow.minSize = initialSize;
  });
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      theme: ThemeData(
        fontFamily: GoogleFonts.poppins().fontFamily,
        colorScheme: ColorScheme.fromSwatch().copyWith(
          primary: const Color.fromRGBO(7, 96, 49, 1),
          secondary: Colors.white,
        ),
      ),
      routes: {
        '/firstPage': (ctx) => const FirstPage(),
        '/loginPage': (ctx) => const LoginPage(),
      },
      home: const MyHomePage(),
    );
  }
}

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

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  late Stream<bool> _authStream;

  @override
  void initState() {
    super.initState();
    // 转换为多订阅流,支持多次监听
    _authStream = FirebaseAuth.instance.signInState.asBroadcastStream();
  }

  @override
  Widget build(BuildContext context) {
    return StreamBuilder(
        stream: _authStream,
        builder: (context, snapshot) {
          if (snapshot.hasData && snapshot.data == true) {
            return const FirstPage();
          } else {
            return const LoginPage();
          }
        });
  }
}

补充说明

  • asBroadcastStream()包装后的流可以被多个订阅者同时监听,不会触发重复监听错误
  • 也可以全局初始化这个广播流,在整个应用中复用,避免重复转换
  • 使用StreamBuilder时无需手动管理订阅生命周期,框架会自动处理

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 22:21:01