【发布时间】:2019-12-14 14:17:03
【问题描述】:
在我的应用中,我使用 Firebase 中的数据构建了一个对象列表。在 StreamBuilder 中,我检查快照是否有数据。如果没有,我将返回一个带有“正在加载...”的简单文本小部件。我的问题是,如果我转到应用程序中的另一个页面,然后再返回,您会在一瞬间看到它在屏幕中间显示“正在加载...”,这有点烦人。我很确定它正在从 Firebase 下载数据,并在我每次返回该页面时构建小部件。如果我不检查数据,它会给我一个我试图从 null 访问数据的数据。
有没有办法缓存已经下载的数据,如果Firebase的数据没有变化,那么就使用缓存的数据?
这是我的代码的修订版本:
class Schedule extends StatefulWidget implements AppPage {
final Color color = Colors.green;
@override
_ScheduleState createState() => _ScheduleState();
}
class _ScheduleState extends State<Schedule> {
List<Event> events;
List<Event> dayEvents;
int currentDay;
Widget itemBuilder(BuildContext context, int index) {
// Some Code
}
@override
Widget build(BuildContext context) {
return Center(
child: StreamBuilder(
stream: Firestore.instance.collection('events').snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Text("Loading...");
}
events = new List(snapshot.data.documents.length);
for (int i = 0; i < snapshot.data.documents.length; i++) {
DocumentSnapshot doc = snapshot.data.documents.elementAt(i);
events[i] = Event(
name: doc["name"],
start: DateTime(
doc["startTime"].year,
doc["startTime"].month,
doc["startTime"].day,
doc["startTime"].hour,
doc["startTime"].minute,
),
end: DateTime(
doc["endTime"].year,
doc["endTime"].month,
doc["endTime"].day,
doc["endTime"].hour,
doc["endTime"].minute,
),
buildingDoc: doc["location"],
type: doc["type"],
);
}
events.sort((a, b) => a.start.compareTo(b.start));
dayEvents = events.where((Event e) {
return e.start.day == currentDay;
}).toList();
return ListView.builder(
itemBuilder: itemBuilder,
itemCount: dayEvents.length,
);
},
),
);
}
}
【问题讨论】:
-
你在什么平台上运行这个应用程序?您使用什么插件来访问 Firestore?在 iOS 和 Android 上,FlutterFire plugin 应该已经在您访问数据后在本地缓存它。当您第一次打开集合上的流时,应将数据添加到缓存中。随后对同一集合的
stream()调用应该“立即”从本地缓存返回数据,然后可能稍后再次触发来自服务器的更新。 -
来自本地缓存的数据(如果启用)不会立即出现在您的应用中。如果可以的话,您必须等待本地缓存满足查询。如果您想要即时结果,请将内容存储在内存中,并且不要使用 SDK 执行其他查询。
标签: firebase caching flutter dart google-cloud-firestore