StreamController с Firestore - PullRequest
       6

StreamController с Firestore

0 голосов
/ 05 февраля 2019

Я хочу использовать StreamController для управления StreamBuilder, который получает данные из коллекции в Firestore.Это позволит мне использовать RefereshIndicator, поэтому, когда я опускаю список, он обновляет / выбирает больше данных, если они есть.

Я использовал большую часть информации в этой статье .Мой текущий код ниже

    class _Lists extends State<List> {
      StreamController _controller;
      final GlobalKey<ScaffoldState> scaffoldKey = new GlobalKey<ScaffoldState>();

        @override
         void initState() {
        _controller = new StreamController();
         loadPosts();         
        super.initState();
        }

       Future fetchPost() async {
       return await . 
       Firestore.instance.collection(_locationState).snapshots();
        }

      Future<Null> _handleRefresh() async {
      count++;
      print(count);
       fetchPost().then((res) async {
       _controller.add(res);
       showSnack();
        return null;
      });
     }

      showSnack() {
      return scaffoldKey.currentState.showSnackBar(
      SnackBar(
      content: Text('New content loaded'),
      ),
       );  
     }

      loadPosts() async {
      fetchPost().then((res) async {
       print(res.document);
       _controller.add(res);
      return res;
      });
      }


       @override
   Widget build(BuildContext context) {
   final topBar = AppBar(Title("List"));
   bottom: TabBar(
    indicatorColor: Colors.blueAccent,
    indicatorWeight: 3.0,
    //indicatorSize: 2.0,
    indicatorPadding:
        const EdgeInsets.only(bottom: 10.0, left: 47.0, right: 
    47.0),
    tabs: [
      Tab(
        child: Image(
          image: AssetImage("MyImage1"),
          width: 65.0,
          height: 65.0,
        ),
      ),
      Tab(
        child: Image(
          image: AssetImage("Image2"),
          width: 90.0,
          height: 90.0,
        ),
      ),
    ],
  ),

return DefaultTabController(
    length: 2,
    child: Scaffold(
        key: scaffoldKey,
        appBar: topBar,
        body: StreamBuilder(
            stream: _controller.stream,
            builder: (BuildContext context, AsyncSnapshot snapshot) {
              if (snapshot.hasError) {
                return Text(snapshot.error);
              }
              if (snapshot.connectionState == ConnectionState.active) {
                List aList = new List();
                aList.clear();
                for (DocumentSnapshot _doc in snapshot.data.documents) {
                  Model _add = new Model.from(_doc);
                  aList.add(_add);
                }
                return TabBarView(
                  children: <Widget>[
                    RefreshIndicator(
                      onRefresh: _handleRefresh,
                      child: ListView.builder(
                        itemCount: aList.length,
                        itemBuilder: (context, index) {
                          return Card(aList[index]);
                        },
                      ),
                    ),
                    Icon(Icons.directions_transit),
                  ],
                );
              } else {
                return Container(
                    child: Center(child: CircularProgressIndicator()));
              }
            })));
 }
}
}

Проблема, с которой я сталкиваюсь, заключается в том, что я получаю ошибку

    flutter: ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY 
╞═══════════════════════════════════════════════════════════
flutter: The following NoSuchMethodError was thrown building 
StreamBuilder<dynamic>(dirty, state:
flutter: _StreamBuilderBaseState<dynamic, 
AsyncSnapshot<dynamic>>#53c04):
flutter: Class '_BroadcastStream<QuerySnapshot>' has no instance getter 'documents'.
flutter: Receiver: Instance of '_BroadcastStream<QuerySnapshot>'
flutter: Tried calling: documents

Любые идеи о том, как использовать StreamController с данными изFirestore?

1 Ответ

0 голосов
/ 05 февраля 2019

Отслеживание типов возвращаемых данных в вашей IDE, вероятно, поможет избежать многих запутанных проблем, подобных этой.К сожалению, этот блог не указывает какие-либо типы для вызова API, StreamController или 'res' в операторе then.Объявление этих типов поможет показать, с чем вы работаете (по крайней мере, в Android Studio).Например, в моем StreamBuilder с потоком из Firestore я использую AsyncSnapshot<QuerySnapshot> snapshot вместо просто AsyncSnapshot.Это позволяет инструментам в Android Studio сообщать мне, что snapshot.data.documents - это карта из класса QuerySnapshot.Если я не добавлю дополнительный тип, я не смогу это увидеть.

Вот пример прослушивания потока из пакета Firestore Dart .

//Performing a query:

Firestore.instance
    .collection('talks')
    .where("topic", isEqualTo: "flutter")
    .snapshots()
    .listen((data: QuerySnapshot) =>
        // do stuff here
    );

Поскольку вы используете стиль async / await (также прекрасно), вы получите тот же результат, что и внутри .listen((data) =>.Мы можем следить за документацией / классами, чтобы увидеть, какие типы возвращаются.

Firestore.instance.collection(<whatever>).snapshots() вернет Stream<QuerySnapshot>, поэтому мы знаем, что await Firestore.instance.collection(<whatever>).snapshots() вернет QuerySnapshot.

Копаем дальшев классе мы видим, что у него есть свойство с именем documents.

  /// Gets a list of all the documents included in this snapshot
  final List<DocumentSnapshot> documents;

Это, наконец, дает нам те DocumentSnapshot s, из которых вам придется извлечь свойство data.

Так что в вашем случае, я считаю, что тип res, являющийся QuerySnapshot, поможет показать вам, какие данные поместить в ваш поток, что можно сделать несколькими способами на данном этапе.List<DocumentSnapshot> похоже, что вы собираетесь, но вы можете пойти дальше к List<YourClass>, построенному из свойства DocumentSnapshot data.При этом вы можете сказать, какой тип данных будет возвращать ваш StreamController, что делает AsyncSnapshot<your stream type> компоновщика намного более понятным для работы.

Я не уверен, какие инструменты разработки вы используете, но на случай, если вы небольшинство знакомых позволят вам сделать что-то вроде: нажмите / удерживайте (команда или Ctrl), наведите курсор на тип / class / function / var, который вы хотите увидеть, щелкните левой кнопкой мыши, и вы должны перейти к исходным файлам / объявлениям.(Я нахожу это супер удобным).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...