Правильное использование потоков с Flutter-Listview

Я пытаюсь отобразить экран чата в реальном времени в flutter с firebase-firestore (равно главному экрану WhatsApp).

Работа: Создание списка всех контактов-пиров. Взгляните на мой список:

Container(
  child: StreamBuilder(
    stream:
        //FirebaseFirestore.instance.collection('users').snapshots(),
        FirebaseFirestore.instance
            .collection('users')
            .doc(currentUserId)
            .collection('peers')
            .snapshots(),
    builder: (context, snapshot) {
      if (!snapshot.hasData) {
        return Center(
          child: CircularProgressIndicator(
            valueColor: AlwaysStoppedAnimation<Color>(themeColor),
          ),
        );
      } else {
        return ListView.builder(
          padding: EdgeInsets.all(10.0),
          itemBuilder: (context, index) =>
              buildItem(context, snapshot.data.documents[index]),
          itemCount: snapshot.data.documents.length,
        );
      }
    },
  ),
),

не работает: загружаются определенные данные для каждой плитки, такие как последнее сообщение или имя. Я не могу запросить это во время создания моего первого списка (первый запрос возвращает одноранговые идентификаторы, второй возвращает пользовательские данные однорангового идентификатора). Мой метод buildItem состоит из другого построителя потоков, однако, как только первый построитель потоков вносит изменения, приложение зависает.

  Widget buildItem(BuildContext context, DocumentSnapshot document) {
      return StreamBuilder<DocumentSnapshot>(
        stream: FirebaseFirestore.instance
            .collection('users')
            .doc(document.data()['peerId'])
            .snapshots(),
        builder: ...

Это правильный способ вложения потоков? Простые списки достаточно хорошо задокументированы, но я не смог найти хороший пример в Google. Любая помощь приветствуется.


person JustAnotherEngineer    schedule 25.10.2020    source источник


Ответы (1)


Попробуйте создать свой поток только один раз в initState и передать его этому методу:

//in initState
peersStream = FirebaseFirestore.instance
            .collection('users')
            .doc(currentUserId)
            .collection('peers')
            .snapshots(),

Затем используйте stream: peersStream в StreamBuilder.

Кроме того, рекомендуется использовать классы виджетов вместо методов для виджетов: https://stackoverflow.com/a/53234826/5066615

person Rohan Taneja    schedule 25.10.2020