简体   繁体   English

Flutter 应用程序全局 state 来自 firebase 文档的流订阅

[英]Flutter app global state frorm streamsubscription of firebase document

I try to make indicator which can show actual status open or close of some place.我尝试制作可以显示某个地方的实际状态打开或关闭的指示器。 To do this I use boolean value from firebase documents field, true for open and false for close.为此,我使用 firebase 文档字段中的 boolean 值,true 表示打开,false 表示关闭。 I made cubit (from bloc) to set a global state for entire application.我做了cubit(来自bloc)来为整个应用程序设置一个全局state。

Technicaly its should work like: Stream form documents filed - converted to my own datamodel - emit stream subscritpion of this like global state end change look of widget depends on state value (switch widget1 or widget2). Technicaly its should work like: Stream form documents filed - converted to my own datamodel - emit stream subscritpion of this like global state end change look of widget depends on state value (switch widget1 or widget2).

My code works, but not what I want.我的代码有效,但不是我想要的。 The widget does not realtime change but after reloading the page.小部件不会实时更改,而是在重新加载页面后。 I'm not sure that my stream code is wrong or the delivery state is wrong.我不确定我的 stream 代码是错误的还是交货 state 是错误的。 Please help, I'm new to flutter.请帮忙,我是 flutter 的新手。

My codes below:我的代码如下:

GlobalDataSource:全球数据源:

class GlobalRemoteDataSource {
//  one time read
  // Future<GlobalDataModel> getGlobalState() async {
  //   final globalState = await FirebaseFirestore.instance
  //       .collection('global')
  //       .doc('states')
  //       .get();
  //   return GlobalDataModel(admin: null, open: globalState['indicator']);
  // }

  Stream<GlobalDataModel> getGlobalStateStream() {
    return FirebaseFirestore.instance
        .collection('global')
        .doc('states')
        .snapshots()
        .map((documentSnapshot) {
      return GlobalDataModel(
          open: documentSnapshot.get('indicator'), admin: null);
    });
  }
}

Cubit:肘:

class RootCubit extends Cubit<RootState> {
  RootCubit(this._globalRemoteDataSource)
      : super(RootState(open: null, admin: false));

  final GlobalRemoteDataSource _globalRemoteDataSource;
  StreamSubscription? _streamSubscription;

  Future<void> initGlobalSteram() async {
    _streamSubscription =
        _globalRemoteDataSource.getGlobalStateStream().listen((state) {
      emit(RootState(open: state.open, admin: state.admin));
    });
  }

  @override
  Future<void> close() {
    _streamSubscription?.cancel();
    return super.close();
  }
}

State implementation for the entire application:整个应用程序的 State 实现:

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

  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      create: (context) =>
          RootCubit(GlobalRemoteDataSource())..initGlobalSteram(),
      child: BlocBuilder<RootCubit, RootState>(
        builder: (context, state) {
          return MaterialApp(
            title: 'Carmel Bakery',
            theme: GlobalTheme(),
            home: AuthGate(),
          );
        },
      ),
    );
  }
}

Place where I use state value:我使用 state 值的地方:

class OfferPageCakes extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final bool? indicator = context.read<RootCubit>().state.open;
    return Scaffold(
      appBar: AppBar(
        leading: indicator == null
            ? Container(
                height: 50, width: 50, child: CircularProgressIndicator())
            : PlaceStatusIndicator(indicator: indicator),
        title: const Center(
          child: Text('CIASTA'),
        ),
        actions: [
          Column(
            children: [
              AnimatedArrowRight(),
              const Text("NAPOJE"),
            ],
          )
        ],
      ),
      body: ListView(
        children: [
          Text('dane z Firebase'),
          indicator == null
              ? Container(
                  height: 50, width: 50, child: CircularProgressIndicator())
              : PlaceStatusIndicator(indicator: indicator)
        ],
      ),
    );
  }
}

Maybe try to wrap your Scaffold in BlocProvider and then declare indicator variable inside.也许尝试将您的 Scaffold 包装在 BlocProvider 中,然后在其中声明指标变量。

  Widget build(BuildContext context) {
    return BlocBuilder<RootCubit, RootState>(
    builder: (context, rootState) {
      final bool? indicator = rootState.open;
      return Scaffold(

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM