我的情况:我正在过滤日期字段,并且我要求它为null
。然而,日期字段不为空的数据库记录却以某种方式通过了。我正在使用 Firebase 模拟器。
我尝试过的:
- 删除除此过滤器之外的所有过滤器,但不起作用。
- 更改其他过滤器(即不在日期字段上)以确保整个流正常工作:检查。
这是应该过滤 finishedTDate == null
的代码块:
FirebaseFirestore.instance
.collection('events')
.where('userId', isEqualTo: userId)
.where('event', isEqualTo: 'createAndSaveItems')
// problem statement:
.where('finishedTDate', isEqualTo: null)
// problem statement ^
.snapshots()
.listen((snapshot) {
var filteredEventData = snapshot.docs.map((doc) {
Map<String, dynamic> data = doc.data();
data['id'] = doc.id;
return data;
}).toList();
streamController5.add(filteredEventData);
});
这是它所在的函数:
Stream<
Tuple5<List<Item>, List<Item>, List<Item>, List<Map<String, dynamic>>,
List<Map<String, dynamic>>>>? getStreams(String userId) {
Timestamp currentTime = Timestamp.now();
Timestamp oneHourFromNow = Timestamp.fromMillisecondsSinceEpoch(
currentTime.millisecondsSinceEpoch + 3600000);
Timestamp oneHourAgo = Timestamp.fromMillisecondsSinceEpoch(
currentTime.millisecondsSinceEpoch - 3600000);
StreamController<List<QueryDocumentSnapshot>> streamController1 =
StreamController();
StreamController<List<QueryDocumentSnapshot>> streamController2 =
StreamController();
StreamController<List<QueryDocumentSnapshot>> streamController3 =
StreamController();
StreamController<List<Map<String, dynamic>>> streamController4 =
StreamController();
StreamController<List<Map<String, dynamic>>> streamController5 =
StreamController();
FirebaseFirestore.instance
.collection('items')
.where('userId', isEqualTo: userId)
.snapshots()
.listen((snapshot) {
var filteredDocs = snapshot.docs.where((doc) {
return (doc['dDate'] as Timestamp).millisecondsSinceEpoch == 0 &&
(doc['sDate'] as Timestamp).millisecondsSinceEpoch == 0;
}).toList();
streamController1.add(filteredDocs);
});
FirebaseFirestore.instance
.collection('items')
.where('userId', isEqualTo: userId)
.snapshots()
.listen((snapshot) {
var filteredDocs = snapshot.docs.where((doc) {
return (doc['due'] as Timestamp).millisecondsSinceEpoch <=
oneHourFromNow.millisecondsSinceEpoch &&
(doc['dDate'] as Timestamp).millisecondsSinceEpoch != 0;
}).toList();
streamController2.add(filteredDocs);
});
FirebaseFirestore.instance
.collection('items')
.where('userId', isEqualTo: userId)
.orderBy('dDate')
.limit(1)
.snapshots()
.listen((snapshot) {
var filteredDocs = snapshot.docs.where((doc) {
return (doc['due'] as Timestamp).millisecondsSinceEpoch >
oneHourFromNow.millisecondsSinceEpoch;
}).toList();
streamController3.add(filteredDocs);
});
FirebaseFirestore.instance
.collection('files')
.where('userId', isEqualTo: userId)
.where('include', isEqualTo: true)
.snapshots()
.listen((snapshot) {
var filteredDocsData = snapshot.docs.map((doc) {
Map<String, dynamic> data = doc.data();
data['id'] = doc.id;
return data;
}).toList();
streamController4.add(filteredDocsData);
});
FirebaseFirestore.instance
.collection('events')
.where('userId', isEqualTo: userId)
.where('event', isEqualTo: 'createAndSaveItems')
.where('finishedTDate', isEqualTo: null)
.snapshots()
.listen((snapshot) {
var filteredEventData = snapshot.docs.map((doc) {
Map<String, dynamic> data = doc.data();
data['id'] = doc.id;
return data;
}).toList();
streamController5.add(filteredEventData);
});
return Rx.combineLatest5(
transformListToItem(streamController1.stream).startWith([]),
transformListToItem(streamController2.stream).startWith([]),
transformListToItem(streamController3.stream).startWith([]),
streamController4.stream.startWith([]),
streamController5.stream.startWith([]),
(List<Item> items1,
List<Item> items2,
List<Item> items3,
List<Map<String, dynamic>> files,
List<Map<String, dynamic>> eventData) =>
Tuple5(items1, items2, items3, files, eventData),
);
}
这是我的调试器中返回的内容:
抱歉,我在错误的变量下划线了,finishedTDate
应该有下划线。
为什么过滤器不起作用?不在日期字段上的过滤器可以工作,这就是为什么我知道这不是我无意中查看了错误的变量。
数据库结构:
最佳答案
此处为 firebaser
我能够在 Flutter 中重现这一点,它与底层 native (Web)SDK 的行为不同。
- Flutter repro (在 Dartpad 中)
- JavaScript non-repro (在 StackBlitz 中)
这个问题不仅发生在我的日期字段上,而且在您尝试检索空值时发生在任何字段上。我只在网络上进行了测试,但这足以将其标记为错误。
我报告了问题 #11874在 FlutterFire 存储库中,因此我建议您关注更新。
更新
其中一位开发人员跟进了我创建的问题,结果发现您必须在 Flutter 中使用 isNull
条件。所以:
FirebaseFirestore.instance
.collection('events')
.where('userId', isEqualTo: userId)
.where('event', isEqualTo: 'createAndSaveItems')
.where('finishedTDate', isNull: true) // 👈
我在 Dartpad 测试台上对其进行了测试,它有效。
关于flutter - Firebase 的过滤器不适用于日期字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77468864/