扑朔迷离中的Firestore快照侦听器数据复制问题

时间:2020-01-24 18:44:18

标签: firebase flutter pagination google-cloud-firestore chat

您好,我正在使用消防商店数据库来在用户之间进行一对一聊天。在这里,我想对消息进行分页。因此,我在 initState 内部调用了快照侦听器,所以问题出在我导航到聊天屏幕时, initState 自动将快照侦听器称为 DocumentType.added 。这样数据就变得重复了。

这是我在 initState

内部调用的代码
List<DocumentSnapshot> _products = [];
StreamController<List<DocumentSnapshot>> _streamController =
StreamController<List<DocumentSnapshot>>.broadcast();

@override
void initState() {
     db
    .collection('chat')
   .document(docId)
    .collection('messages')
    .orderBy('timestamp', descending: true)
    .snapshots().listen((data) => onChangeData(
          data.documentChanges,
        ));
}
void onChangeData(
  List<DocumentChange> documentChanges,
) {
  documentChanges.forEach((productChange) {
    if (productChange.type == DocumentChangeType.removed) {
      _products.removeWhere((product) {
        return productChange.document.documentID == product.documentID;
      });

      _streamController.add(_products);
    }
    if (productChange.type == DocumentChangeType.added) {
    _products.insert(productChange.newIndex, productChange.document);
      _streamController.add(_products);
    }
    if (productChange.type == DocumentChangeType.modified) {
      int indexWhere = _products.indexWhere((product) {
        return productChange.document.documentID == product.documentID;
      });

      if (indexWhere >= 0) {
        _products[indexWhere] = productChange.document;
      }

      _streamController.add(_products);   
    }
  });
}

1 个答案:

答案 0 :(得分:1)

这是正常现象-当您将侦听器附加到文档或集合时,您首先会得到一个包含当前数据的回调,然后在数据发生更改时进行后续调用。

由于您正在使用分页,并在每个页面的initState内附加了新的侦听器,因此每次页面更改时都会得到第一个回调。

您应该做的是创建一个单独的类,该类负责侦听您的集合并通知所有应更新的小部件。您可以使用选择的状态管理库来通知小部件数据更改。