Flutter Firebase:使用流生成器时如何删除Firebase侦听器?

时间:2019-06-18 11:35:50

标签: firebase flutter google-cloud-firestore

即使在StreamBuilder示例中,每个关于StatelessWidget的示例都以flutter开头,但是如何在StatelessWidget小部件中取消订阅?例如,我正在经历firestore example

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);
    });
 }
}

2 个答案:

答案 0 :(得分:2)

只需用null替换以前的流实例。

这将需要类似于以下内容的代码:

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

这样做将停止收听流。但是StreamBuilder仍将保留以前的值。

答案 1 :(得分:0)

我遇到了同样的问题,并通过 StreamSubscription

解决了

例如,将 StreamSubscription 定义为全局

StreamSubscription<Event> _counterSubscription;

然后在您要收听数据的地方像这样注册您的订阅

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

,当您想删除监听器时,只需编写以下代码

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