firebase - 在 initState() 中放置两个 Firestore.instances
问题描述
现在这可能是一个很好的做法,或者完全不!
我试图抵制在StreamBuilder
下面放置更多(s)build(BuildContext context)
并尝试使用initState()
。Future
由于没有正确使用// async
,我遇到了麻烦await
。( String _leaseTenantName
first initState()
Firestore.instance
) 将具有正确的值,但 Strings _leaseUnitName
& _leaseUnitPropertyUid
(second 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
s?
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(
解决方案
这是一个很大的不。
首先,使用 multiple 并没有错StreamBuilder
,StreamBuilder
帮助您简化使用,Streams
这样您就不会像在initState()
.
当您像在listen()
上snapshots()
一样调用时initState()
,您创建了一个订阅,该订阅应该在 上取消dispose()
,但您没有取消它,因此您正在那里泄漏内存,aStreamBuilder
会在它为您管理时将您保存在这里。
要记住的另一件事是您正在使用_leaseUnitPropertyUid
on build()
,但您不检查是否_leaseUnitPropertyUid
有效。_leaseUnitPropertyUid
只会在Firebase
snapshot()
Stream
发出一个值之后设置,并且build()
可以在此之前调用。再次,StreamBuilder
将您保存在这里,并且您可以检查它是否已发出值。
此外,您正在Firebase.instance
对代码进行硬编码,这使得测试变得非常困难。查看依赖注入并尝试将其注入Firebase.instance
到您的类中,例如存储库模式或类似的东西,这样您就可以将其替换Firebase.instace
为测试Mock并使您的代码更具可测试性。
推荐阅读
- javascript - 无法弄清楚这个while循环的问题
- c - 使用 Open62541 的 OPC UA 客户端服务器连接
- ios - 如何从 UIFont 实例中检索当前系统设计?
- three.js - 可以在 ThreeJS 中为场景添加颜色色调吗?
- javascript - devServer 代理缺少 URL 部分
- javascript - Ionic 5 离子刷新问题当我们也使用离子手势时
- c# - nuget 中的 DLL 引用版本 = 0.0.0.0
- python - 无法在 PyCharm 中运行 unittest 测试套件(使用 TestCase 子类),而它在 Python 控制台中运行
- go - 如何处理非准备好的语句占位符
- debugging - 如何使用 PureScript 进行调试?