带Firestore的StreamController [英] StreamController with Firestore

查看:45
本文介绍了带Firestore的StreamController的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用一个 StreamController 来控制一个 StreamBuilder 来从<$ c $中的集合中获取数据c> Firestore 。这将使我能够使用 RefereshIndicator ,以便在下拉列表时刷新/获取更多数据。

I want to user a StreamController to control a StreamBuilder that gets data from a collection in Firestore. This will enable me to use a RefereshIndicator so that when I pull down on the list, it refreshes/ fetches more data if there is any.

我使用了文章。我当前的代码低于

I used most of the information in this article. My current code is below

    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()));
              }
            })));
 }
}
}

我遇到的问题是我一直收到错误

The Problem I have with this is I keep getting the error

    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 中的数据一起使用的任何想法?

Any ideas on how to go about using the StreamController with data from Firestore ?

推荐答案

密切关注IDE中的返回类型将可能有助于避免此类令人困惑的问题。很遗憾,该博客未在then语句中指出API调用,StreamController或 res的任何类型。声明这些类型将有助于显示您正在使用的对象(至少对我来说在Android Studio中有用)。例如,在带有Firestore流的StreamBuilder中,我使用 AsyncSnapshot< QuerySnapshot>快照,而不只是 AsyncSnapshot 。这使Android Studio中的工具可以告诉我 snapshot.data.documents QuerySnapshot 类的映射。如果我不添加额外的类型,则看不到。

Keeping a close eye on return types in your IDE will likely help avoid a lot of confusing issues like this. Unfortunately, that blog does not indicate any types for the API call, StreamController, or 'res' in the then statement. Having those types declared will help show what you are working with (at least it does for me in Android Studio). For example in my StreamBuilder with a stream from Firestore, I use AsyncSnapshot<QuerySnapshot> snapshot instead of just AsyncSnapshot. This allows the tools in Android Studio to tell me that snapshot.data.documents is the map from the QuerySnapshot class. If I don't add the extra type, I can't see that.

这里是从 Firestore Dart程序包

//Performing a query:

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

由于您使用的是异步/等待风格(也很好),因此相同的结果将出现在 .listen((data)=> ..我们可以按照文档/类查看返回的类型。

Since you're using the async/await style (also perfectly fine), you'll have the same result that will be inside of .listen((data) =>. We can follow the documentation/classes to see what types are returned.

Firestore.instance.collection(< whatever>)。s​​napshots()
将返回
Stream< QuerySnapshot>
,因此我们知道
等待Firestore.instance.collection(< whatever>)。s​​napshots()
将返回
QuerySnapshot

进一步挖掘到类,我们看到它有一个名为 documents 的属性。

Digging further into the class, we see it has a property called documents.

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

这最终为我们提供了 DocumentSnapshot ,您必须从中提取 data 属性。

This finally gives us those DocumentSnapshots, which you'll have to pull the data property from.

所以在哟在这种情况下,我相信 res 类型为 QuerySnapshot 可以帮助您显示要在流中放入哪些数据,此时可以通过多种方式完成。 List< DocumentSnapshot> 看起来像您想要的东西,但是您可以走得更远一些 List< YourClass> 是从 DocumentSnapshot data 属性构建的。这样,您可以说出StreamController将返回哪种数据类型,从而使构建器的 AsyncSnapshot<您的流类型> 更加易于使用。

So in your case, I believe the res type being QuerySnapshot will help show you what data to put in your stream, which can be done multiple ways at this point. List<DocumentSnapshot> seems to look like what you're going for, but you could go farther to List<YourClass> built from the DocumentSnapshot data property. With that, you can say what data type your StreamController will return, making the builder's AsyncSnapshot<your stream type> much more clear to work with.

我不确定您使用的是什么开发工具,但是如果您不熟悉,大多数工具将允许您执行以下操作:按下/按住(命令或ctrl),将鼠标悬停在类型上/ class / function / var要查看,请单击鼠标左键,然后您将被带到源文件/声明(我觉得这很方便)。

I'm not sure what development tools you are using, but in case you aren't familiar most will allow you to do something like: press/hold (command or ctrl), hover over the type/class/function/var you want to see, left click, and you should be taken to the source files/declarations (I find this super handy).

这篇关于带Firestore的StreamController的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆