【问题标题】:How to get data from multiple firebase collections using a Stream Builder如何使用 Stream Builder 从多个 firebase 集合中获取数据
【发布时间】:2021-05-27 09:23:45
【问题描述】:

My flutter app

我在使用流构建器访问 firebase 中两个不同集合的数据时遇到问题。我有一个名为 ForumPage 的 StatefulWidget,上面有一张图片。 ForumPage 有一列有多个子级,其中一个是 MyStreamBuilder StatelessWidget。这是我用来连接到 firebase 的小部件。

MyStreamBuilder

import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:hotel_for_dogs/Posts/need_post.dart';
import 'package:hotel_for_dogs/Posts/sitter_post.dart';

class MyStreamBuilder extends StatelessWidget {
  final String _typeOfPost;
  final String _state;
  final String _city;
  MyStreamBuilder(this._typeOfPost, this._state, this._city);

  @override
  Widget build(BuildContext context) {
    Stream stream = FirebaseFirestore.instance.collection(_typeOfPost).where('state', isEqualTo: _state).where('city', isEqualTo: _city).snapshots();
    return SizedBox(
        height: 400,
        child: StreamBuilder<QuerySnapshot>(
          // needPosts
        stream: stream,
        builder: (context, snapshot) {
          if (snapshot.hasData && snapshot.data.size > 0) {
            final List<DocumentSnapshot> documents = snapshot.data.docs;
            if(_typeOfPost == "needPosts") {
              return ListView(
                  children: documents
                      .map((doc) => Card( child: NeedPost(
                      doc['title'],
                      doc['dogBreed'],
                      doc['dogNeeds'],
                      doc['amountOfTime'],
                      doc['amountPerHour'],
                      doc['pottyTrained'],
                      doc['animalFriendly'],
                      doc['date'],
                      doc['state'],
                      doc['city'],
                      doc['dogName'],
                      doc['email'],
                      doc['phone'],
                      doc['fullName'])
                  ))
                      .toList());
            } else {
              return ListView(
                  children: documents
                      .map((doc) => Card( child: SitterPost(
                      doc['title'],
                      doc['amountPerHour'],
                      doc['date'],
                      doc['state'],
                      doc['city'],
                      doc['email'],
                      doc['phone'],
                      doc['fullName'],
                      doc['breedSize'],
                      doc['bio'],
                      doc['fencedBackYard'],
                      doc['otherAnimals'])
                  ))
                      .toList());
            }
          } else if (snapshot.hasError) {
            return Text("error");
          } else if(!snapshot.hasData){
            return Center(
              child: CircularProgressIndicator(),
            );
          } else {
            return Text("No Data");
          }
            }));
  }
}

当用户输入州和城市时,他们可以点击“我是保姆”按钮,然后点击搜索。需要保姆的人的帖子会出现(当然如果有数据的话)。当用户点击“需要保姆”按钮时,就会出现保姆的帖子。当点击搜索按钮时,处理选择显示哪种帖子。这是该代码和另一张图片的代码!

My flutter app with some data entered

 setState(() {
                      if (iAmSitterColor == Colors.black && stateController.text.isNotEmpty && cityController.text.isNotEmpty) {
                        typeOfPost = "needPosts";
                        state = stateController.text;
                        city = cityController.text;
                      } else if (needASitterColor == Colors.black && stateController.text.isNotEmpty && cityController.text.isNotEmpty) {
                        typeOfPost = "sitterPosts";
                        state = stateController.text;
                        city = cityController.text;
                      }
                    });

设置状态会触发 UI 重建,因此 MyStreamBuilder 将获得更新的信息。

MyStreamBuilder(typeOfPost, state, city)

您可能已经从上一张图片中注意到,此代码可以正常工作,并且确实可以从 Firestore 中正确获取数据。但是,如果我在两个按钮之间切换并点击搜索,会出现一个红色屏幕,然后会出现帖子。当我的终端发生这种情况时,我会收到此错误

The following StateError was thrown building StreamBuilder<QuerySnapshot>(dirty, state: _StreamBuilderBaseState<QuerySnapshot, AsyncSnapshot<QuerySnapshot>>#fdcd8):
Bad state: field does not exist within the DocumentSnapshotPlatform

我想知道有没有更好的方法来做到这一点?我也厌倦了将 MyStreamBuilder 更改为:

import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:hotel_for_dogs/Posts/need_post.dart';
import 'package:hotel_for_dogs/Posts/sitter_post.dart';

class MyStreamBuilder extends StatelessWidget {
  final String _typeOfPost;
  final String _state;
  final String _city;
  MyStreamBuilder(this._typeOfPost, this._state, this._city);

  @override
  Widget build(BuildContext context) {
    Stream stream1 = FirebaseFirestore.instance.collection("needPosts").where('state', isEqualTo: _state).where('city', isEqualTo: _city).snapshots();
    Stream stream2 = FirebaseFirestore.instance.collection("sitterPosts").where('state', isEqualTo: _state).where('city', isEqualTo: _city).snapshots();

    if (_typeOfPost == "needPosts"){
      return SizedBox(
          height: 400,
          child: StreamBuilder<QuerySnapshot>(
            // needPosts
              stream: stream1,
              builder: (context, snapshot) {
                if (snapshot.hasData && snapshot.data.size > 0) {
                  final List<DocumentSnapshot> documents = snapshot.data.docs;
                  return ListView(
                      children: documents
                          .map((doc) => Card( child: NeedPost(
                          doc['title'],
                          doc['dogBreed'],
                          doc['dogNeeds'],
                          doc['amountOfTime'],
                          doc['amountPerHour'],
                          doc['pottyTrained'],
                          doc['animalFriendly'],
                          doc['date'],
                          doc['state'],
                          doc['city'],
                          doc['dogName'],
                          doc['email'],
                          doc['phone'],
                          doc['fullName'])
                      ))
                          .toList());
                } else if (snapshot.hasError) {
                  return Text("error");
                } else if(!snapshot.hasData){
                  return Center(
                    child: CircularProgressIndicator(),
                  );
                } else {
                  return Text("No Data");
                }
              }));
    } else {
      return SizedBox(
          height: 400,
          child: StreamBuilder<QuerySnapshot>(
            // needPosts
              stream: stream2,
              builder: (context, snapshot) {
                if (snapshot.hasData && snapshot.data.size > 0) {
                  final List<DocumentSnapshot> documents = snapshot.data.docs;
                  return ListView(
                      children: documents
                          .map((doc) => Card( child: SitterPost(
                          doc['title'],
                          doc['amountPerHour'],
                          doc['date'],
                          doc['state'],
                          doc['city'],
                          doc['email'],
                          doc['phone'],
                          doc['fullName'],
                          doc['breedSize'],
                          doc['bio'],
                          doc['fencedBackYard'],
                          doc['otherAnimals'])
                      ))
                          .toList());
                } else if (snapshot.hasError) {
                  return Text("error");
                } else if(!snapshot.hasData){
                  return Center(
                    child: CircularProgressIndicator(),
                  );
                } else {
                  return Text("No Data");
                }
              }));
    }
  }
}

它给了我同样的错误。我应该使用未来的建设者吗?我只看到未来的构建器被用来访问集合中的特定文档数据。我需要的是集合中的所有文档数据。

【问题讨论】:

  • 尝试将您的 doc['FIELD_NAME'] 更改为 doc.data()['FIELD_NAME'],这可能会使错误消失。让我知道这是否有效。
  • 我被震撼了。我现在有一个没有错误的工作解决方案。谢谢你,先生。回答问题并将其标记为已回答。
  • 答案已发布:)

标签: firebase flutter dart google-cloud-firestore


【解决方案1】:

发生这种情况是因为您没有正确地从 firestore 获取数据以在地图上进行设置。

要删除该警告,您需要在地图设置期间将代码中的 doc[FIELD_NAME] 结构更改为 doc.data()[FIELD_NAME]

【讨论】:

猜你喜欢
  • 2021-03-06
  • 2020-09-08
  • 2021-07-23
  • 2020-07-30
  • 2021-07-25
  • 2021-06-01
  • 2021-03-05
  • 1970-01-01
  • 2018-03-24
相关资源
最近更新 更多