简体   繁体   English

Firestore 集合查询为 flutter 中的 stream

[英]Firestore collection query as stream in flutter

I'm trying to query a few documents from a collection, this query should listen to changes made in the queried documents, so I'd need a stream. I'm doing following (in Dart/Flutter)我正在尝试从集合中查询一些文档,此查询应该监听查询文档中所做的更改,因此我需要一个 stream。我正在执行以下操作(在 Dart/Flutter 中)

  Stream<List<MatchRequest>> _getNewMatches() {
    return Collection<MatchRequest>(path: 'requests')
        .ref
        .where('status', isNull: true)
        .where('users', arrayContains: ['$currentUid'])
        .orderBy('last_activity')
        .snapshots()
        .map((list) => list.documents.map(
            (doc) => Global.models[MatchRequest](doc.data) as MatchRequest));
  }

(The object Collection sets the path to the ref in it's constructor, eg: ref = db.collection($path) and the map makes a model of the results) (object Collection 在其构造函数中设置 ref 的路径,例如:ref = db.collection($path) 和 map 生成结果的 model)

Then I'm using a StreamBuilder with stream invoking the method above and builder checking if snapshot.hasData.然后我使用带有 stream 的stream调用上面的方法和builder检查是否 snapshot.hasData。 But it keeps loading, snapshot.hasData keeps being false.但它一直在加载,snapshot.hasData 一直是错误的。 What am I doing wrong here?我在这里做错了什么?

EDIT:编辑:

  1. My firestore security rules contain:我的 Firestore 安全规则包含:

     match /requests/{requestId} { allow read: if isLoggedIn(); allow write: if isLoggedIn(); }
  2. When removing every where and orderBy , it doesn't find anything as well.当删除每个whereorderBy ,它也找不到任何东西。 And there are documents present in the requests-collection并且请求集合中存在文档

  3. When trying to query only 1 document as a stream from the requests-collection, he does find the result当试图从请求集合中仅查询 1 个文档作为 stream 时,他确实找到了结果

  4. Is it because I should add indexes to my firestore indexes?是因为我应该将索引添加到我的 firestore 索引中吗? But this won't solve my first problem which is that even without where and orderBy , it doesn't get any data但这并不能解决我的第一个问题,即即使没有whereorderBy ,它也得不到任何数据

I've written a simple example of it seems to be like what you are trying to do but are missing the listen() method:我写了一个简单的例子,它似乎就像你想要做的,但缺少 listen() 方法:

Firestore.instance.collection('collection')
  .where('field', isEqualTo: 'value')
  .orderBy('field')
  .snapshots()
  .listen((QuerySnapshot querySnapshot){
    querySnapshot.documents.forEach((document) => print(document));
  }
);

This is just an example of how you can take the data from a Firestore Stream and use it on a StreamBuilder:这只是一个示例,说明如何从 Firestore Stream 获取数据并在 StreamBuilder 上使用它:

class _MyHomePageState extends State<MyHomePage> {
  Stream dataList;

  @override
  void initState() {
    dataList = Firestore.instance.collection('collection')
      .where('field', isEqualTo: 'value')
      .orderBy('field')
      .snapshots();

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: StreamBuilder(
          stream: dataList,
          builder: (context, asyncSnapshot) {
            if(asyncSnapshot.hasError)
              return Text('Error: ${asyncSnapshot.error}');

            switch (asyncSnapshot.connectionState) {
              case ConnectionState.none: return Text('No data');
              case ConnectionState.waiting: return Text('Awaiting...');
              case ConnectionState.active:
                return ListView(
                  children: asyncSnapshot.data.map((document) => Text(document['value'])),
                );
              break;
              case ConnectionState.done: return ListView(
                children: asyncSnapshot.data.map((document) => Text(document['value'])),
              );
              break;
            }
            return null;
        }),
      ),
    );
  }

} 

1. Multiple Documents 1. 多份文件

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: StreamBuilder<QuerySnapshot>(
          stream: FirebaseFirestore
                  .instance.
                  .collection('users') // 👈 Your desired collection name here
                  .snapshots(), 
          builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
            if (snapshot.hasError) {
              return const Text('Something went wrong');
            }
            if (snapshot.connectionState == ConnectionState.waiting) {
              return const Text("Loading");
            }
            return ListView(
                children: snapshot.data!.docs.map((DocumentSnapshot document) {
              Map<String, dynamic> data =
                  document.data()! as Map<String, dynamic>;
              return ListTile(
                title: Text(data['fullName']), // 👈 Your valid data here
              );
            }).toList());
          },
        ),
      ),
    );
  }

2. Single Document 2. 单一文件

 @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: StreamBuilder<DocumentSnapshot<Map<String, dynamic>>>(
          stream:  FirebaseFirestore
                   .instance
                   .collection('users')
                   .doc(FirebaseAuth.instance.currentUser!.uid) // 👈 Your document id change accordingly
                   .snapshots(), 
          builder:
              (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
            if (snapshot.hasError) {
              return const Text('Something went wrong');
            }
            if (snapshot.connectionState == ConnectionState.waiting) {
              return const Text("Loading");
            }
            Map<String, dynamic> data =
                snapshot.data!.data()! as Map<String, dynamic>;
            return Text(data['fullName']); // 👈 your valid data here
          },
        ),
      ),
    );
  }

Also refer: How to use StreamBuilder and FutureBuilder for single and multiple documents另请参阅: How to use StreamBuilder and FutureBuilder for single and multiple documents

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM