为什么我不能使用提供程序包在 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。
我正在为此苦恼,我需要你们的帮助。请帮我解决这个问题。
我目前正在从 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
的 classclass 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。