【发布时间】:2022-01-19 13:42:36
【问题描述】:
我正在尝试流式传输我的 firebase firestore 字段。这是我的数据库中的代码。它在按钮中工作,我可以打印我想要的。但实际上我想使用 StreamBuilder 在我的主页中显示带有小部件的数据。
getYukListFromDB() async {
_firebaseFirestore
.collection('customer')
.get()
.then((QuerySnapshot querySnapshot) {
for (var docA in querySnapshot.docs) {
debugPrint("shipment altındaki docs idsi = " + docA.id);
_firebaseFirestore
.collection('customer')
.doc(docA.id)
.collection('myYuks')
.get()
.then((QuerySnapshot querySnapshot) {
for (var docB in querySnapshot.docs) {
debugPrint("myYuk altındaki docs idsi = " + docB.id);
_firebaseFirestore
.collection('customer')
.doc(docA.id)
.collection('myYuks')
.doc(docB.id)
.get()
.then((DocumentSnapshot documentSnapshot) {
Map<String, dynamic> mapData =
documentSnapshot.data()! as Map<String, dynamic>;
if (documentSnapshot.exists) {
debugPrint("icerik = ${mapData['icerik']}");
debugPrint('doc var');
} else {
debugPrint('doc yok');
}
});
}
});
}
});
}
当我在流中尝试这个时,它给了我一个错误。
Stream<List<YukModel>> yeniYukStream(String uid) { // ***error here***
_firebaseFirestore
.collection('customer')
.get()
.then((QuerySnapshot querySnapshot) {
for (var doc1 in querySnapshot.docs) {
debugPrint("shipment altındaki docs idsi = " + doc1.id);
return _firebaseFirestore
.collection("customer")
.doc(doc1.id)
.collection('myYuks')
.get()
.then((QuerySnapshot querySnapshot) {
for (var doc2 in querySnapshot.docs) {
debugPrint("myYuk altındaki docs idsi = " + doc2.id);
_firebaseFirestore
.collection('customer')
.doc(doc2.id)
.collection('myYuks')
.orderBy('createTime', descending: true)
.snapshots()
.map((QuerySnapshot querySnapshot) {
List<YukModel> retVal = <YukModel>[];
for (var lastData in querySnapshot.docs) {
retVal.add(YukModel.fromDocumentSnapshot(lastData));
}
return retVal;
});
}
});
}
});
}
主体可能正常完成,导致返回“null”,但返回类型可能是不可为空的类型。 尝试在末尾添加 return 或 throw 语句。
而且我知道它应该是未来。让我们试试吧。
Future<Stream<List<YukModel>>> yeniYukStream(String uid) async{
return _firebaseFirestore
.collection('customer')
.get()
.then((QuerySnapshot querySnapshot) { // ****error here****
for (var doc1 in querySnapshot.docs) {
debugPrint("shipment altındaki docs idsi = " + doc1.id);
return _firebaseFirestore
.collection("customer")
.doc(doc1.id)
.collection('myYuks')
.get()
.then((QuerySnapshot querySnapshot) { // ****error here****
for (var doc2 in querySnapshot.docs) {
debugPrint("myYuk altındaki docs idsi = " + doc2.id);
_firebaseFirestore
.collection('customer')
.doc(doc2.id)
.collection('myYuks')
.orderBy('createTime', descending: true)
.snapshots()
.map((QuerySnapshot querySnapshot) {
List<YukModel> retVal = <YukModel>[];
for (var lastData in querySnapshot.docs) {
retVal.add(YukModel.fromDocumentSnapshot(lastData));
}
return retVal;
});
}
});
}
});
}
****错误****行是这样的:
主体可能正常完成,导致返回“null”,但返回类型可能是不可为空的类型。 尝试在末尾添加 return 或 throw 语句。
这是我的 YukModel.dart 文件;
class YukModel {
String? yukID;
String? yukBaslik;
String? icerik;
int? agirlik;
Timestamp? createTime;
String? aracTipi;
bool? onayDurumu;
YukModel(
{this.yukID,
this.yukBaslik,
this.icerik,
this.agirlik,
this.createTime,
this.aracTipi,
this.onayDurumu});
YukModel.fromDocumentSnapshot(DocumentSnapshot documentSnapshot) {
yukID = documentSnapshot.id;
yukBaslik = documentSnapshot.get('yukBaslik');
icerik = documentSnapshot.get('icerik');
agirlik = documentSnapshot.get('agirlik');
createTime = documentSnapshot.get('createTime');
aracTipi = documentSnapshot.get('aracTipi');
onayDurumu = documentSnapshot.get('onayDurumu');
}
}
我该怎么办?另外,我正在使用 GetX 包进行状态管理。
我现在的解决方案
这是我的解决方案。它对我有用。此外,您可以使用此代码访问您的子集合。
在 HomePage 中,我添加了一个 StreamBuilder:
StreamBuilder(
stream: FirebaseFirestore.instance
.collection("customer")
.doc(authController.doneUser!.uid) // you can use your uid
.collection("myYuks")
.snapshots(),
builder: (BuildContext context,
AsyncSnapshot<QuerySnapshot<Map<String, dynamic>>> snapshot) {
if (snapshot.hasData && snapshot.data != null) {
if (snapshot.data!.docs.isNotEmpty) {
return ListView.builder(
itemBuilder: (context, int index) {
Map<String, dynamic> docData =
snapshot.data!.docs[index].data();
if (docData.isEmpty) {
return const Center(child: Text("Data empty"));
}
//these are my fields in subcollections.
// you can use like docData["yourfieldnameinsubcollection"];
String yukID = docData[FirestoreFields.yukID];
String yukBaslik = docData[FirestoreFields.yukBaslik];
String icerik = docData[FirestoreFields.icerik];
String agirlik = docData[FirestoreFields.agirlik];
return Card(
child: Container(
color: ColorConstants.birincilRenk,
height: 210,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Wrap(
children: [
Text(yukID, style: const TextStyle(fontSize: 16)),
const Divider(thickness: 1),
Text(yukBaslik,
style: const TextStyle(fontSize: 20)),
const Divider(thickness: 1),
Text(icerik, style: const TextStyle(fontSize: 16)),
const Divider(thickness: 1),
Text(agirlik, style: const TextStyle(fontSize: 16)),
],
),
),
),
);
},
itemCount: snapshot.data!.docs.length,
);
} else {
return const Text("no data ");
}
} else {
return const Text("loading");
}
},
),
【问题讨论】:
-
我在这里用 // **** 错误标记它****。查看第二个和第三个代码块。
-
看起来 firebase 承诺失败了。用 streambuilder 包装你的 firebase 调用。在您的异步函数 getData 中调用 firebase 端点,然后将数据返回到流构建器。尝试捕获 getData。
-
@GoldenLion 的最后一条评论对您有帮助吗?如果是,您能否请金狮将其添加为帮助社区的答案?谢谢。
-
我自己想出来的。
-
@TolgaYılmaz 您能否将解决方案添加为帮助社区解决相同问题的答案?谢谢。
标签: firebase flutter google-cloud-firestore future flutter-getx