Firebase Flatter中的Firestore快照侦听器数据重复问题

Firebase Flatter中的Firestore快照侦听器数据重复问题,firebase,flutter,pagination,google-cloud-firestore,chat,Firebase,Flutter,Pagination,Google Cloud Firestore,Chat,你好,我正在使用fire store数据库在用户之间进行一对一的聊天。在这里,我想要一些信息分页。所以我在initState中调用了snapshot listener,所以问题是当我导航到聊天屏幕时,initState自动添加了snapshot listener DocumentType。因此数据变得重复 这是我在initState中调用的代码 这是正常的行为—当您将侦听器附加到文档或集合时,首先会收到一个包含当前数据的回调,然后在数据发生更改时进行后续调用 因为您正在使用分页,并在每个页面的i

你好,我正在使用fire store数据库在用户之间进行一对一的聊天。在这里,我想要一些信息分页。所以我在initState中调用了snapshot listener,所以问题是当我导航到聊天屏幕时,initState自动添加了snapshot listener DocumentType。因此数据变得重复

这是我在initState中调用的代码


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

因为您正在使用分页,并在每个页面的initState中附加一个新的侦听器,所以每次页面更改都会得到第一个回调


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

您正在将文档更改列表传递到onChangeData方法中。这是您以前在本地拥有的数据和来自Firestore的新数据之间筛选的列表吗?你提到这是一个1对1的聊天,但你的变量是_产品这些是消息吗?清除顶部的列表,然后add@João Soares对错误的变量声明表示抱歉..产品在列表中_products@BloodLoss请给我看一本书好吗demo@SouravDas你能回答我的第一个问题吗。您正在将文档更改列表传递给onChangeData方法。这是您之前在本地拥有的数据和来自Firestore的新数据之间筛选过的列表吗?坦率地说,不是,因为我上面描述的内容没有困难。这很费时,我没有时间。除此之外,你的代码不是由别人编写的,而是让你可以找到你不知道答案的问题的答案。我认为,我已经很清楚地解释了为什么你有你的问题,什么会解决它。实际上我知道如何与国家管理,如集团或供应商,但问题是换听者需要从某处调用,我感到困惑……例如,如果你使用供应商,您将创建一个扩展ChangeNotifier的类。此类将附加Firestore侦听器,该侦听器将依次调用onChangeData函数,该函数将在适当时更新_产品并调用notifyListeners。您只有一个通过提供程序公开的ChangeNotifier实例。现在,您的每个页面只需调用build方法中的某个地方的Provider.ofcontext,以便在调用notifyListeners时重新生成。因此,您从changenotifier类调用onchange listener的地方…如何实现这一点?您将onChangeData函数与_产品以及其中的任何其他内容一起移动到changenotifier。。。
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);   
    }
  });
}