现在,这也许是一种很好的做法,或者完全不行!
我试图抵制在StreamBuilder
下放置更多build(BuildContext context)
,然后尝试使用initState()
。由于无法正确使用Future
/ async
/ await
,我遇到了麻烦。 String _leaseTenantName
(第一个initState()
Firestore.instance
)将具有正确的值,但字符串_leaseUnitName
和_leaseUnitPropertyUid
(第二个initState()
Firestore.instance
)通常将返回null。以下内部版本的StreamBuilder<PropertyDetails>
会给出错误消息'Invalid document reference. Document references must have an even number of segments, but properties has 1, null)'
,但会继续尝试,并在_leaseUnitPropertyUid
最终具有值时最终起作用。
我相信解决方案是以某种方式将两个initState()
Firestore.instances
包装在Future
/ async
/ await
中,但无法解决此问题。有任何想法吗??还是应该使用更多嵌套的StreamBuilder
?
class _LeaseTileState extends State<LeaseTile> {
String _leaseTenantName = '';
String _leaseUnitPropertyUid = '';
String _leaseUnitName = '';
String _leasePropertyName = '';
String _leasePropertyUnitName = '';
@override
void initState() {
super.initState();
Firestore.instance
.collection("companies")
.document(widget.leaseDetails.tenantUid)
.snapshots()
.listen((snapshot) {
_leaseTenantName = snapshot.data['companyName'];
});
Firestore.instance
.collection("units")
.document(widget.leaseDetails.unitUid)
.snapshots()
.listen((snapshot) {
_leaseUnitName = snapshot.data['unitName'];
_leaseUnitPropertyUid = snapshot.data['propertyUid'];
});
}
@override
Widget build(BuildContext context) {
final user = Provider.of<User>(context);
return StreamBuilder<PropertyDetails>(
stream: DatabaseServices(propertyUid: _leaseUnitPropertyUid)
.propertyByDocumentID,
builder: (context, userCompany) {
if (!userCompany.hasData) return Loading();
_leasePropertyName = userCompany.data.propertyName;
_leasePropertyUnitName = '$_leasePropertyName - $_leaseUnitName';
return Card(
最佳答案
那是很大的不。
首先,使用多个StreamBuilder
并没有错,StreamBuilder
可以帮助您简化Streams
的使用,因此您最终不会像在initState()
中那样弄乱他们的订阅。
当您像在listen()
上一样在snapshots()
上调用initState()
时,创建了一个订阅,该订阅应在dispose()
上取消,但是您不取消它,因此您泄漏了内存,StreamBuilder
会在您管理时将您保存在此处这个给你。
要记住的另一件事是,您在_leaseUnitPropertyUid
上使用build()
,但是您不检查_leaseUnitPropertyUid
是否有效。仅在_leaseUnitPropertyUid
Firebase
snapshot()
发出一个值并且可以在此之前调用Stream
后才设置build()
。同样,StreamBuilder
将在这里保存您,您可以检查它是否发出了值。
另外,您还在代码上对Firebase.instance
进行硬编码,这使得测试非常困难。看一看Dependency Injection并尝试将Firebase.instance
注入(inject)到您的类中,例如Repository模式或类似的东西,以便您可以将Firebase.instace
交换为测试Mock,并使您的代码更具可测试性。
关于firebase - 将两个Firestore.instances放置在initState()中,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/62096582/