为什么我不能使用提供程序包在 Flutter 中从 Cloud Firestore 获取最后一个文档?

Why can't I get last document from cloud firestore in flutter using provider package?

我正在为此苦恼,我需要你们的帮助。请帮我解决这个问题。

我目前正在从 firestore 获取流并且工作正常,但问题是我现在和当前都想实现分页,我无法获取最后一个文档的值,这就是我无法使用 startAfter 的原因特征。看看我的代码

父页面上的代码,即 homepage.dart

StreamProvider<List<Cars>>.value(
  value: DatabaseService().getCars(),
  catchError: (ctx, err) => null,
  child: ChangeNotifierProvider(
    create: (context) => LastDocumentTracker(),
    child: Scaffold()

数据库服务页面上的代码:

getCars({bool getMore = false}) {
    var collection = carsCollection.orderBy('dueDate').limit(15);
 if(!getMore )   {
   return collection.snapshots().map((event) {


     LastDocumentTracker().changeLastDocument(event.docs.last);
     return _carsListFromSnapshot(event);
   });
 }


  }

现在我得到了一个带有 ChangeNotifier

的 class
class LastDocumentTracker with ChangeNotifier{

  List <QueryDocumentSnapshot> _snapshot = [];


  QueryDocumentSnapshot  get getLastDocument {


     return _snapshot.last;

  }


  void changeLastDocument (QueryDocumentSnapshot doc){
    print('Snapshot $_snapshot'); // here I can see the snapshot on console but on other pages where I am listinig its null. 

    _snapshot.add(doc);

    notifyListeners();
  }
 }

我想从 getter getLastDocument 获取最后一个文档的值,但是我无法获取它,因为它始终为空。

请帮我实现分页,因为我不希望用户一次访问一大堆数据。

每次执行 LastDocumentTracker() 时,您都在使用 _snapshot = [] 创建 LastDocumentTracker 的新实例。因此,您将最后一个元素设为空。将 LastDocumentTracker 转换为单例:

class LastDocumentTracker with ChangeNotifier{

  static LastDocumentTracker _instance;

  List <QueryDocumentSnapshot> _snapshot;

  LastDocumentTracker._construct() {
      _snapshot = [];
  }

  factory LastDocumentTracker() {
      if(_instance == null) _instance = LastDocumentTracker._construct();
      return _instance;
  }

  QueryDocumentSnapshot  get getLastDocument {
     return _snapshot.last;
  }

  void changeLastDocument (QueryDocumentSnapshot doc) {

    _snapshot.add(doc);

    notifyListeners();
  }
 }

编辑

正如您提到的提供商,最好不要使用我提供的单例答案。相反,您可以替换为:

LastDocumentTracker().changeLastDocument(event.docs.last);

final tracker = Provider.of<LastDocumentTracker>(context, listen: false);
tracker.changeLastDocument(event.docs.last);

这样,您就可以访问您的提供者持有的跟踪器实例。这比我提到的单例模式要好,因为它使 class 可以使用提供程序重用。

注:

  • 您需要上下文来访问该上下文的提供者,因此无论您在哪里调用它,都将上下文传递给 getCars 方法。

  • 设置 listen 为 false 否则,您将无法从 buttonPress 回调或 initState 等方法访问 getCars。