Почему мой поток Firestore выдает повторяющиеся результаты в моем forEach на snaphot?

#flutter #google-cloud-firestore

# #flutter #google-облако-firestore

Вопрос:

Я пытаюсь действовать в соответствии с определенным типом изменения документа в моем потоке Firestore. Я заметил, что когда документ добавляется или удаляется, я получаю несколько копий при повторном просмотре снимка. Я слушаю поток в своем дереве виджетов с отслеживанием состояния, но я нигде не вызываю setState. Вот соответствующий код:

 @override Widget build(BuildContext context) {
var usersOnStreamQuery =  placeCollection.doc(place).collection('usersOn');

...

body: Builder(builder: (BuildContext context) {
              usersOnStreamQuery
                  .snapshots(includeMetadataChanges: true)
                  .listen((data) {
                data.docChanges.forEach((change) {
                  String type;
                  print(
                      'document type ${change.type} on doc ${change.doc.data()}');
                  switch (change.type) {
                    case DocumentChangeType.added:
                      type = 'joined';
                      break;
                    case DocumentChangeType.removed:
                      type = 'left';
                      break;
                    default:
                  }
 

Количество раз, когда о каждом сообщается, изменяется, но я заметил, что я получаю одинаковое количество каждого за сеанс. Например, это для одного и того же документа:

 flutter: document type DocumentChangeType.added on doc {x: 60, y: 7}
flutter: document type DocumentChangeType.added on doc {x: 60, y: 7}
flutter: document type DocumentChangeType.added on doc {x: 60, y: 7}
flutter: document type DocumentChangeType.added on doc {x: 60, y: 7}
flutter: document type DocumentChangeType.added on doc {x: 60, y: 7}
 

а затем такое же количество ниже, когда документ удаляется. В обоих случаях я ожидаю только один и могу проверить, что в моей коллекции firestore есть только один документ.

 flutter: document type DocumentChangeType.removed on doc {x: 60, y: 7}
flutter: document type DocumentChangeType.removed on doc {x: 60, y: 7}
flutter: document type DocumentChangeType.removed on doc {x: 60, y: 7}
flutter: document type DocumentChangeType.removed on doc {x: 60, y: 7}
flutter: document type DocumentChangeType.removed on doc {x: 60, y: 7}
 

Комментарии:

1. Можете ли вы добавить точку останова или оператор печати во вторую строку функции сборки, потому что я думаю, что это случай, когда функция сборки вызывается несколько раз, а не проблема с несколькими документами в моментальном снимке. Оператор печати функции сборки подтвердит это

2. @FemiAdegoke, это была хорошая мысль, но я добавил точку останова и все равно получаю несколько дублей за 1 перерыв при добавлении. При получении нескольких удаленных типов он даже не попадает в разрыв при запуске виджета. Есть другие предложения?

3. Пробовали ли вы печатать data перед вызовом forEach , чтобы убедиться, что вы получаете повторяющиеся уведомления, а не просто одно уведомление печатается из-за нескольких build вызовов?

4. @Lee3, хорошее предложение. Я получаю несколько Instance of 'QuerySnapshot при печати раньше data , чем раньше forEach . Означает ли это, что это определенно связано с перестройкой виджета? Как я могу предотвратить множественные потоки в этом случае? Я начинаю прослушивать поток в своем виджете, потому что хочу отображать данные на основе потока. Есть ли лучший способ сделать это?

5. Вот что это такое. Вы создаете слушателя при каждом вызове сборки. Используйте StreamBuilder.