【问题标题】:Flutter Firebase: How to remove firebase listener when using stream builder?Flutter Firebase:使用流构建器时如何删除 Firebase 侦听器?
【发布时间】:2019-11-01 01:07:12
【问题描述】:

关于StreamBuilder 的每个示例都以StatelessWidget 开头,即使在flutter 示例中也是如此,但是如何取消StatelessWidget 小部件中的订阅?例如,我正在通过firestoreexample

class MessageList extends StatelessWidget {
 MessageList({this.firestore});

 final Firestore firestore;

 @override
 Widget build(BuildContext context) {
 return StreamBuilder<QuerySnapshot>(
  stream: firestore.collection('messages').snapshots(),
  builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
    if (!snapshot.hasData) return const Text('Loading...');
    final int messageCount = snapshot.data.documents.length;
    return ListView.builder(
      itemCount: messageCount,
      itemBuilder: (_, int index) {
        final DocumentSnapshot document = snapshot.data.documents[index];
        return ListTile(
          title: Text(document['message'] ?? '<No message retrieved>'),
          subtitle: Text('Message ${index + 1} of $messageCount'),
        );
      },
    );
  },
 );
 }
}

现在如何取消收听firestore.collection('messages').snapshots() 流?

我在我的应用程序中使用实时数据库,我就是这样做的

class MessgaeView extends StatefulWidget {
 final String _chatId;
 MessgaeView(this._chatId);

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

class _MessgaeViewState extends State<MessgaeView> {
 Stream<Event> _messageStream;
 @override
 void initState() {
  _messageStream = _database
    .reference()
    .child("message/${widget._chatId}")
    .limitToLast(1)
    .onChildAdded;
  super.initState();
 }

 @override
 void dispose() {
  _messageStream.drain();
  super.dispose();
 }
@override
Widget build(BuildContext context) {
return StreamBuilder(
    stream: _messageStream,
    builder: (context, snapshot) {
      if (!snapshot.hasData) return CupertinoActivityIndicator();
      final message =
          (snapshot.data.snapshot as DataSnapshot).value['message'];
      return Text(message);
    });
 }
}

【问题讨论】:

    标签: firebase flutter google-cloud-firestore


    【解决方案1】:

    我有同样的问题,StreamSubscription

    解决了

    例如将 StreamSubscription 定义为全局

    StreamSubscription<Event> _counterSubscription;
    

    然后在你想听数据的地方注册你的订阅,像这样

    _counterSubscription = _counterRef.onValue.listen((Event event) {
          setState(() {
            _counter = event.snapshot.value ?? 0;
          });
     });
    

    当你想删除监听器时,只需编写此代码

    if(_counterSubscription !=null)
         _counterSubscription .cancel();
    

    【讨论】:

      【解决方案2】:

      只需将之前的流实例替换为null

      这将需要类似于以下某处的代码:

      setState(() {
        _messageStream = null;
      });
      

      这样做将停止收听流媒体。但StreamBuilder 仍会保留之前的值。

      【讨论】:

      • 感谢您的回答。我的问题是在哪里停止听?通常在有状态的widget中,我们可以通过dispose方法释放资源
      • 啊,因为你没有什么可做的。 Firebase 的流不必被处理掉,StreamBuilder 已经负责在需要时停止订阅。
      • 我刚刚浏览了StreamBuilder 源代码,它在dispose 方法上调用了unsubscribe。谢谢,@Rémi Rousselet。您能否将此信息添加到答案中。它会帮助别人。
      • 如果我想关闭ist,我应该把_messageStream = null 放入dispose吗?我问是因为流在子小部件中运行。
      猜你喜欢
      • 2019-01-24
      • 1970-01-01
      • 2021-08-13
      • 2015-09-07
      • 1970-01-01
      • 2014-02-27
      • 2017-03-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多