flutter - Firebase 的过滤器不适用于日期字段

标签 flutter firebase dart google-cloud-firestore

我的情况:我正在过滤日期字段,并且我要求它为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),
  );
}

这是我的调试器中返回的内容:

enter image description here

抱歉,我在错误的变量下划线了,finishedTDate 应该有下划线。

为什么过滤器不起作用?不在日期字段上的过滤器可以工作,这就是为什么我知道这不是我无意中查看了错误的变量。

数据库结构:

enter image description here

最佳答案

此处为 firebaser

我能够在 Flutter 中重现这一点,它与底层 native (Web)SDK 的行为不同。

这个问题不仅发生在我的日期字段上,而且在您尝试检索空值时发生在任何字段上。我只在网络上进行了测试,但这足以将其标记为错误。

我报告了问题 #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/

相关文章:

flutter - Flutter bool 变量未更新

flutter - 我首先要打开 ExpansionTile 的项目默认值。我想当我点击另一个项目时,当前项目将关闭。我该怎么做?

javascript - 从表单将文件添加到 vue.js 中的 firebase 存储

flutter - 验证并仅允许 TextField 中的日期和连字符——MaskTextInputFormatter 不适用于手动更新文本

ios - 使用 Alamofire 从 Firebase 检索 JSON

firebase - 访问云功能中的云 Firestore 文档

ios - 不受支持的架构,.app/Frameworks/...的可执行文件包含 Flutter ios 上不受支持的架构 [x86_64]

dart - 从 Github 编译 Spark

flutter - 如何在Flutter中将Row()小部件的末端保持元素?

android - 在flutter中的异步函数中捕获PlatformException