为什么我不能使用提供程序包在颤振中从 cloud firestore 获取最后一个文档?

时间:2021-02-12 01:42:37

标签: flutter dart google-cloud-firestore stream

我对此很头疼,我需要你们的帮助。请帮我解决这个问题。

我目前正在从 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 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 中获取最后一个文档的值,但是我无法获取它,因为它始终为 null。

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

1 个答案:

答案 0 :(得分:0)

每次执行 LastDocumentTracker() 时,您都在使用 _snapshot = [] 创建 LastDocumentTracker 的新实例。因此,您将最后一个元素设为 null。将 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);

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

注意:

  • 您需要上下文来访问该上下文的提供者,因此将上下文从您调用它的任何地方传递给 getCars 方法。

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