Flutter / Firebase - Список ‹dynamic› не имеет экземпляров получателей 'документов'

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

    The following NoSuchMethodError was thrown building StreamBuilder<dynamic>(dirty, state: _StreamBuilderBaseState<dynamic, AsyncSnapshot<dynamic>>#25b40):
Class 'List<dynamic>' has no instance getter 'documents'.
Receiver: _List len:2
Tried calling: documents

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

Stream<QuerySnapshot> getDefaultOccasions(BuildContext context) async*{
  yield* Firestore.instance.collection('datestoremember').document('default').collection('Dates_to_Remember').snapshots();
}

Stream<QuerySnapshot> getPersonalOccasions(BuildContext context) async*{
  final uid = await Provider.of(context).auth.getCurrentUID();
  yield* Firestore.instance.collection('datestoremember').document(uid).collection('Dates_to_Remember').snapshots();
}

 getData() {
  Stream stream1 = Firestore.instance.collection('datestoremember').document('default').collection('Dates_to_Remember').snapshots();
  Stream stream2 = Firestore.instance.collection('datestoremember').document('Ngrx54m84JbsL0tGvrBeKCBlEnm2').collection('Dates_to_Remember').snapshots();
  return StreamZip([stream1, stream2]);
}

Затем я реализую это здесь:

              child: StreamBuilder(
            stream: getData(),
            builder: (context, snapshot) {
              if(!snapshot.hasData) return const Text("Loading...");
              return new PageView.builder(
                itemCount: snapshot.data.documents.length,
                controller: PageController(viewportFraction: 0.5),
                onPageChanged: (int index) => setState(() => _index = index),
                itemBuilder: (_, i) {
                  return Transform.scale(
                    scale: i == _index ? 1 : 0.5,
                    child: Card(
                      elevation: 6,
                      shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(10)),
                      child: Column(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          Text(snapshot.data.documents[i]['Date'].toDate().day.toString()),
                          Text(DateFormat.MMMM()
                              .format(
                              formatter.parse(snapshot.data.documents[i]['Date'].toDate().toString()))
                              .toString()),
                          Padding(
                            padding: const EdgeInsets.only(
                                left: 8.0, right: 8.0),
                            child: FittedBox(
                              fit: BoxFit.contain,
                              child: Text(
                                snapshot.data.documents[i]['Title'],
                                overflow: TextOverflow.ellipsis,
                              ),
                            ),
                          )
                        ],
                      ),
                    ),
                  );
                },
              );},
          ),

Любые идеи? Ваше здоровье


person TJMitch95    schedule 02.09.2020    source источник


Ответы (1)


Попробуй это:

getData() {
  Stream stream1 = Firestore.instance.collection('datestoremember').document('default').collection('Dates_to_Remember').snapshots();
  Stream stream2 = Firestore.instance.collection('datestoremember').document('Ngrx54m84JbsL0tGvrBeKCBlEnm2').collection('Dates_to_Remember').snapshots();

  return StreamGroup.merge([stream1, stream2]).asBroadcastStream();
}

ИЗМЕНИТЬ с помощью StreamZip:

Stream<List<QuerySnapshot>> getData() {
  Stream stream1 = Firestore.instance.collection('datestoremember').document('default').collection('Dates_to_Remember').snapshots();
  Stream stream2 = Firestore.instance.collection('datestoremember').document('Ngrx54m84JbsL0tGvrBeKCBlEnm2').collection('Dates_to_Remember').snapshots();
  return StreamZip<List<QuerySnapshot>>([stream1, stream2]);
}

И в StreamBuilder:

child: StreamBuilder(
        stream: getData(),
        builder: (BuildContext context, AsyncSnapshot<List<QuerySnapshot>> snapshot) {

          List<QuerySnapshot> combinedSnapshot = snapshot.data.toList();
          combinedSnapshot[0].documents.addAll(combinedSnapshot[1].documents);

          if(!combinedSnapshot[0].hasData) return const Text("Loading...");
          return new PageView.builder(
            itemCount: combinedSnapshot[0].data.documents.length,
            controller: PageController(viewportFraction: 0.5),
            onPageChanged: (int index) => setState(() => _index = index),
            itemBuilder: (_, i) {
              return Transform.scale(
                scale: i == _index ? 1 : 0.5,
                child: Card(
                  elevation: 6,
                  shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(10)),
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      Text(combinedSnapshot[0].data.documents[i]['Date'].toDate().day.toString()),
                      Text(DateFormat.MMMM()
                          .format(
                          formatter.parse(combinedSnapshot[0].data.documents[i]['Date'].toDate().toString()))
                          .toString()),
                      Padding(
                        padding: const EdgeInsets.only(
                            left: 8.0, right: 8.0),
                        child: FittedBox(
                          fit: BoxFit.contain,
                          child: Text(
                            combinedSnapshot[0].data.documents[i]['Title'],
                            overflow: TextOverflow.ellipsis,
                          ),
                        ),
                      )
                    ],
                  ),
                ),
              );
            },
          );},
      ),
person Ruben Röhner    schedule 02.09.2020
comment
Спасибо, Рубен, это устранило мои ошибки, но объединенный, кажется, отображает только один из исходных потоков за раз, а не объединенный, как я надеялся. Есть идеи, как это обойти? - person TJMitch95; 02.09.2020
comment
Затем я бы предложил использовать StreamZip, как вы это делали раньше, и попробовать передать этот StreamZip. Я обновил свой ответ. - person Ruben Röhner; 02.09.2020
comment
Спасибо, я внес изменения, но теперь столкнулся с новой ошибкой: тип «_MapStream‹ QuerySnapshotPlatform, QuerySnapshot ›» не является подтипом типа «Stream‹ Stream ‹QuerySnapshot› ›», есть мысли? - person TJMitch95; 02.09.2020
comment
Возможно, замените Stream ‹QuerySnapshot› ›только на QuerySnapshot в вашем Cast - person Ruben Röhner; 02.09.2020
comment
Это возвращает меня к моей исходной ошибке: у класса List ‹QuerySnapshot› нет экземпляра получателя документов. Получатель: _List len: 2 Пытался позвонить: документы - тем не менее, оцените ваши предложения - person TJMitch95; 02.09.2020
comment
О, ладно, теперь я понял. Ваш StreamZip предоставляет вам Stream, который содержит список QuerySnapshot. Первая запись этого списка - это QuerySnapshot вашего stream1, а вторая - QuerySnapshot вашего stream2. - person Ruben Röhner; 02.09.2020
comment
Хорошо, это имеет смысл, я могу получить доступ к отдельным потокам путем индексации, но мне нужно объединить оба потока в один поток данных (устраняя необходимость индексации), как лучше всего этого добиться? - person TJMitch95; 02.09.2020
comment
Спасибо, Рубен, я думаю, что нужно сделать пару настроек, так как я получаю пару ошибок, первая: оператор '[]' не определен для типа 'AsyncSnapshot ‹dynamic›' при объединении снимков (в частности, часть индекса) и вторая: геттер 'data' не определен для типа 'QuerySnapshot'. при доступе к sharedSnapshot.data.documents.length - person TJMitch95; 02.09.2020
comment
Я обновил функцию getData () и конструктор внутри StreamBuilder. - person Ruben Röhner; 02.09.2020
comment
и теперь я получаю: Тип аргумента «Функция виджета (BuildContext, List ‹QuerySnapshot›)» не может быть назначен типу параметра «Функция виджета (BuildContext, AsyncSnapshot ‹dynamic›)» - person TJMitch95; 02.09.2020
comment
Я снова обновил StreamBuilder. Теперь должно работать. - person Ruben Röhner; 02.09.2020
comment
Боюсь, что нет, вот новая ошибка: тип «_MapStream‹ QuerySnapshotPlatform, QuerySnapshot ›» не является подтипом типа «Stream‹ List ‹QuerySnapshot› ›» - возможно, мне стоит переосмыслить свой подход - person TJMitch95; 02.09.2020
comment
Вы можете попробовать добавить возвращаемый тип к вашей функции getData (), как я сделал в своем ответе - person Ruben Röhner; 02.09.2020
comment
Я не уверен, какой тип возвращаемого значения мне следует добавить, какие-либо предложения? - person TJMitch95; 03.09.2020