StreamBuilder 的 Firebase 查询出现并立即消失
Posted
技术标签:
【中文标题】StreamBuilder 的 Firebase 查询出现并立即消失【英文标题】:StreamBuilder's Firebase query appears and disappears instantly 【发布时间】:2021-10-09 23:50:57 【问题描述】:我正在尝试查询一个 Stream,其中文档应该在 'unit' 数组中包含 'UretimKurulum' 和 '日期'应该等于或大于今天的日期。
在流式传输此查询时,我确实在短短几秒钟内得到了我想要的正确结果,然后它显示“无可用数据”。
下面是实际代码:
final FirebaseFirestore _db = FirebaseFirestore.instance;
final DateTime _now = DateTime.now();
final String val = 'UretimKurulum';
@override
Widget build(BuildContext context)
return StreamBuilder<QuerySnapshot<Object>>(
stream: _db.collection('Schedule').where('date', isGreaterThanOrEqualTo: _now).where('unit', arrayContains: val).snapshots(),
builder: (context, snapshot)
if (snapshot.connectionState == ConnectionState.waiting)
return Center(child: LinearProgressIndicator());
else
if (!snapshot.hasData)
return Center(child: Text('No Data Available'));
else
return ListView.builder(
itemCount: snapshot.data!.docs.length,
itemBuilder: (context, index)
var docSnap = snapshot.data!.docs[index];
return Text(docSnap.id);
,
);
,
);
如果我尝试删除:
if (!snapshot.hasData)
return Center(child: Text('No Data Available'));
我收到以下错误:
════════ Exception caught by widgets library ═══════════════════════════════════
The following TypeErrorImpl was thrown building StreamBuilder<QuerySnapshot<Object>>(dirty, state: _StreamBuilderBaseState<QuerySnapshot<Object>, AsyncSnapshot<QuerySnapshot<Object>>>#0508a):
Unexpected null value.
【问题讨论】:
这个问题是否与 Firestore 中的复合查询索引有关?调试控制台不显示添加索引的链接。 您可以尝试将|| snapshot.data == null
添加到if (!snapshot.hasData)
行。不知道会不会有什么效果,但值得一试。
@JaffaKetchup 不幸的是它没有效果
【参考方案1】:
第一件事
//instead of DateTime
final DateTime _now = DateTime.now();
//you should use Timestamp which is provided by Firebase Firestore
final Timestamp timeNow = Timestamp.now();
第二件事
//instead of
where('unit', arrayContains: val)
//try this
where("unit", "arrayContains", val)
希望它应该可以工作,如果没有然后回复我,我会尝试找到其他解决方案。
【讨论】:
【参考方案2】:当您没有在 Firestore 中创建必要的索引时,您会闪烁。您需要为涉及 >、>=、
"collectionGroup": "Schedule",
"queryScope": "COLLECTION",
"fields": [
"fieldPath": "unit",
"arrayConfig": "CONTAINS"
,
"fieldPath": "date",
"order": "ASCENDING"
]
,
或者,如果您愿意,也可以从 Firestore 控制台手动执行。
【讨论】:
【参考方案3】:确实,正如@blaneyneil 和我之前所说的那样,这是一个索引问题。
解决方案是从 Firebase 控制台创建一个复合集合索引,并将字段“todoUnit”索引为数组,将“日期”索引为升序。
【讨论】:
【参考方案4】:-
为什么要尝试删除检查数据?,如果数据为空或为空,一般标准的 UX 应该不显示任何数据。为了避免 null,您可以使用像
data ?? 'default-data'
或 data == null ? 'no-data' : 'found-data'
这样的 elvis 运算符
适合日期时间的条件是使用DateTime.now().microsecondsSinceEpoch
而不是DateTime.now()
这个可选但更精确的数据有效 https://docs.w3cub.com/dart~2/dart-core/datetime/microsecondssinceepoch
你可以试试改变
// instead of
if (!snapshot.hasData)
return Center(child: Text('No Data Available'));
else
return ListView.builder(
itemCount: snapshot.data!.docs.length,
itemBuilder: (context, index)
var docSnap = snapshot.data!.docs[index];
return Text(docSnap.id);
,
);
// try this
if (!snapshot.hasData)
return Center(child: Text('No Data Available'));
return ListView.builder(
itemCount: snapshot.data!.docs.length,
itemBuilder: (context, index)
var docSnap = snapshot.data!.docs[index];
return Text(docSnap.id);
,
);
【讨论】:
以上是关于StreamBuilder 的 Firebase 查询出现并立即消失的主要内容,如果未能解决你的问题,请参考以下文章
使用 Firebase 收听 Stream 的结果与 StreamBuilder 不同
StreamBuilder 的 Firebase 查询出现并立即消失
使本地图像直接出现在聊天中,而不是等待网络图像(Streambuilder / Firebase)
Flutter/Firebase:如何减少对推送/弹出调用的 StreamBuilder 调用?
Flutter 在使用 StreamBuilder 从 firebase 加载数据之前显示红色错误屏幕,如何解决?
Flutter - 使用 StreamBuilder 从 firebase 获取数据后,如何使用 ScrollController 跳转到列表视图的底部?