从firebase获取数据时如何过滤颤振中的项目

从firebase获取数据时如何过滤颤振中的项目,firebase,flutter,dart,google-cloud-firestore,Firebase,Flutter,Dart,Google Cloud Firestore,我目前正在使用FirebaseFirestore.instance.collection('cars').get()从firebase获取与汽车详细信息相关的数据。 我正在List\u cars=[]中保存所有的Car实例 使用我在didChangeDependencies{}中执行的addCarsToList方法 Future<void> addCarsToList({BuildContext context, FilterBy filter}) async { var l

我目前正在使用
FirebaseFirestore.instance.collection('cars').get()
从firebase获取与汽车详细信息相关的数据。 我正在
List\u cars=[]中保存所有的Car实例
使用我在
didChangeDependencies{}
中执行的
addCarsToList
方法

Future<void> addCarsToList({BuildContext context, FilterBy filter}) async {
    var lastDocTracker =
        Provider.of<LastDocumentTracker>(context, listen: false);

    try {
      var dcs = filter != null
          ? await carsCollection.orderBy('dueDate').limit(5).where('readyToRepair', isEqualTo: false).get()
          : await carsCollection.orderBy('dueDate').limit(5).get();

//print(dcs.docs.last.data());

      for (int i = 0; i < dcs.docs.length; i++) {
        Cars carValue = singleCar(dcs, i);

        if (_cars.every((item) => item.carId != carValue.carId)) {
          _cars.add(carValue);
          notifyListeners();
        }
      }
      lastDocTracker.changeLastDocument(dcs.docs.last);
    } catch (e) {
      print(e);
    }
  }
我目前面临的问题是我有三个过滤器(全部、即将出现、准备就绪)

全部指来自firebase且无任何过滤器的所有车辆

即将上市指未来即将上市的汽车。(在Firestore中另存为DateTime.millissecondssinceepoch)

Ready表示准备维修的汽车(在firestore中保存为bool)

我正在尝试使用
where((元素)=>isReadyToRepair)进行过滤
浏览车辆列表并使用setState,但不幸的是,我将其限制为Firebase中的5项,如果没有字段为isReadyToRepair=true的车辆,则我无法向下滚动并使用scroll controller调用getMore,因此它显示为空且未加载任何数据


我需要你们的帮助。请帮帮我。如果我没有很好地解释,请告诉我。

如果您想在此时获得它们5,您需要对数据库进行3次不同的查询并使用where方法,您有文档

您的查询将更像这样:

var dcs = await carsCollection
    .orderBy('dueDate')
    .where('ready', isEqualTo: true)
    .startAfterDocument(lastSnap)
    .limit(5)
    .get();
--更新

对不起,那不符合主题。您需要在LastDocumentTracker中创建两个不同的引用。我假设您将跟踪的最后一个文档存储在一个变量中,所以我要做的是为过滤后的文档创建一个(或为您应用的每个过滤器创建一个),并为所有文档创建一个。然后,当您获得文档时,您将根据应用的过滤器找到正确的变量。为了提高代码的维护性和优雅性,我将使用addCarsToList获取更多和第一次获取它们:

//New addCarsToList
Future<void> addCarsToList(LastDocumentTracker tracker, {FilterBy filter}) async { //Tracker as required and filter as optional
    
    bool hasFilter = filter != null;

    var lastSnap = tracker.getLastSnap(filtered: hasFilter);

    bool isFirst = lastSnap != null;

    var dcs;
        
    try {
      if(hasFilter){
            dcs = isFirst ? await carsCollection.orderBy('dueDate').limit(5).where('readyToRepair', isEqualTo: false).get() : await carsCollection.orderBy('dueDate').startAfterDocument(lastSnap).limit(5).where('readyToRepair', isEqualTo: false).get()
      } else{

        dcs = isFirst ? await carsCollection.orderBy('dueDate').limit(5).get(); : await carsCollection.orderBy('dueDate').startAfterDocument(lastSnap).limit(5).get();
      }

      for (var doc in dcs.docs) {
        Cars carValue = singleCar(doc); // Make it get a single document, what's the point on passing both a list and an index ?

        if (_cars.every((item) => item.carId != carValue.carId)) { //questionable
          _cars.add(carValue);
          notifyListeners();
        }
      }

      lastDocTracker.changeLastDocument(dcs.docs.last, filtered: hasFilter);
    } catch (e) {
      print(e);
    }
  }
//新建addCarsToList
未来的addCarsToList(LastDocumentTracker跟踪器,{FilterBy filter})异步{//tracker(根据需要)和filter(可选
bool hasFilter=filter!=null;
var lastSnap=tracker.getLastSnap(已筛选:hasFilter);
bool isFirst=lastSnap!=null;
var dcs;
试一试{
if(hasFilter){
dcs=isFirst?等待carsCollection.orderBy('dueDate').limit(5)。其中('readyToRepair',isEqualTo:false)。get():等待carsCollection.orderBy('dueDate')。startAfterDocument(lastSnap)。limit(5)。其中('readyToRepair',isEqualTo:false)。get()
}否则{
dcs=isFirst?wait carscolection.orderBy('dueDate').limit(5.get();:wait carscolection.orderBy('dueDate').startAfterDocument(lastSnap).limit(5.get();
}
用于(dcs.docs中的var单据){
Cars carValue=singleCar(doc);//让它得到一个文档,传递列表和索引有什么意义?
如果(_cars.every((item)=>item.carId!=carValue.carId)){//
_汽车。增加(汽车价值);
notifyListeners();
}
}
lastDocTracker.changeLastDocument(dcs.docs.last,过滤:hasFilter);
}捕获(e){
印刷品(e);
}
}
我修改了很多东西,仔细研究了所有这些,如果你不明白,请告诉我。在此之后,您应该做很多调整,例如:

  • 在跟踪程序中为筛选的项目添加变量
  • 在changeLastDocument中添加“filtered”参数并修改右侧 基于此参数的变量
  • 将跟踪器而不是上下文传递给方法(当传递对象时,传递的是它的引用,而不是副本,因此如果修改它,将修改传递的对象;)
  • 修改singleCar方法以接受对象而不是列表和索引

如果您想在5次查询时获得它们,您需要对数据库进行3次不同的查询,并使用where方法,您就有了文档

您的查询将更像这样:

var dcs = await carsCollection
    .orderBy('dueDate')
    .where('ready', isEqualTo: true)
    .startAfterDocument(lastSnap)
    .limit(5)
    .get();
--更新

对不起,那不符合主题。您需要在LastDocumentTracker中创建两个不同的引用。我假设您将跟踪的最后一个文档存储在一个变量中,所以我要做的是为过滤后的文档创建一个(或为您应用的每个过滤器创建一个),并为所有文档创建一个。然后,当您获得文档时,您将根据应用的过滤器找到正确的变量。为了提高代码的维护性和优雅性,我将使用addCarsToList获取更多和第一次获取它们:

//New addCarsToList
Future<void> addCarsToList(LastDocumentTracker tracker, {FilterBy filter}) async { //Tracker as required and filter as optional
    
    bool hasFilter = filter != null;

    var lastSnap = tracker.getLastSnap(filtered: hasFilter);

    bool isFirst = lastSnap != null;

    var dcs;
        
    try {
      if(hasFilter){
            dcs = isFirst ? await carsCollection.orderBy('dueDate').limit(5).where('readyToRepair', isEqualTo: false).get() : await carsCollection.orderBy('dueDate').startAfterDocument(lastSnap).limit(5).where('readyToRepair', isEqualTo: false).get()
      } else{

        dcs = isFirst ? await carsCollection.orderBy('dueDate').limit(5).get(); : await carsCollection.orderBy('dueDate').startAfterDocument(lastSnap).limit(5).get();
      }

      for (var doc in dcs.docs) {
        Cars carValue = singleCar(doc); // Make it get a single document, what's the point on passing both a list and an index ?

        if (_cars.every((item) => item.carId != carValue.carId)) { //questionable
          _cars.add(carValue);
          notifyListeners();
        }
      }

      lastDocTracker.changeLastDocument(dcs.docs.last, filtered: hasFilter);
    } catch (e) {
      print(e);
    }
  }
//新建addCarsToList
未来的addCarsToList(LastDocumentTracker跟踪器,{FilterBy filter})异步{//tracker(根据需要)和filter(可选
bool hasFilter=filter!=null;
var lastSnap=tracker.getLastSnap(已筛选:hasFilter);
bool isFirst=lastSnap!=null;
var dcs;
试一试{
if(hasFilter){
dcs=isFirst?等待carsCollection.orderBy('dueDate').limit(5)。其中('readyToRepair',isEqualTo:false)。get():等待carsCollection.orderBy('dueDate')。startAfterDocument(lastSnap)。limit(5)。其中('readyToRepair',isEqualTo:false)。get()
}否则{
dcs=isFirst?wait carscolection.orderBy('dueDate').limit(5.get();:wait carscolection.orderBy('dueDate').startAfterDocument(lastSnap).limit(5.get();
}
用于(dcs.docs中的var单据){
Cars carValue=singleCar(doc);//让它得到一个文档,传递列表和索引有什么意义?
如果(_cars.every((item)=>item.carId!=carValue.carId)){//
_汽车。增加(汽车价值);
notifyListeners();
}
}
lastDocTracker.changeLastDocument(dcs.docs.last,过滤:hasFilter);
}捕获(e){
印刷品(e);
}
}
我修改了很多东西,仔细研究了所有这些,如果你不明白,请告诉我。在此之后,您应该做很多调整,例如:

  • 艾丁