【发布时间】:2021-05-27 09:23:45
【问题描述】:
我在使用流构建器访问 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