我很好奇。如果您从服务器读取了所有之前的文档,您的账单将会因为读取次数过多而增加。
如果发生这种情况,任何人都将无法使用 Firestore。
我确认,如果您使用 Future,您可以使用 getOption 启用缓存。
但是,无论我在StreamBuilder中如何搜索,都找不到任何与缓存相关的选项。
让我向您展示一些简单的代码。
StreamBuilder<QuerySnapshot<Map<String, dynamic>>>(
stream: db
.collection('user')
.doc(docId)
.collection('friendList')
.snapshots(includeMetadataChanges: true),
builder: (context,
AsyncSnapshot<QuerySnapshot<Map<String, dynamic>>>
snapshot) {
if (snapshot.connectionState == ConnectionState.active) {
Logger().d('New message');
if (snapshot.hasData) {
final friendDoc = snapshot.data!.docs;
Logger().d('access message ${friendDoc.length}');
}
}
if (snapshot.connectionState == ConnectionState.waiting) {
Logger().d('why?');
return const Center(
child: SizedBox(
width: 20,
height: 20,
child: CircularProgressIndicator()),
);
}
if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
}
if (!snapshot.hasData || snapshot.data == null) {
return const Center(
child: Text('No data available'),
);
}
final friendDoc = snapshot.data!.docs;
return ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: friendDoc.length,
itemBuilder: (context, index) {
final friendId = snapshot.data!.docs[index].id;
return FutureBuilder(
future: FirebaseFirestore.instance
.collection('user')
.doc(friendId)
.get(const GetOptions(source: Source.cache)),
builder: (context,
AsyncSnapshot<
DocumentSnapshot<Map<String, dynamic>>>
snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) {
return const SizedBox(
width: 20,
height: 20,
child:
CircularProgressIndicator());
}
当我运行应用程序并检查它从 Firestore 读取的内容时,我发现它正在从服务器读取。我很沮丧。
如何让 StreamBuilder 首先读取 Firestore 缓存?
当然,如果客户端缓存里没有东西,我想从服务器读取,然后从缓存读取。
此外,当创建新数据时,很自然地只在第一次从服务器读取它。
我想从缓存中读取我已经读过的旧材料。
我需要帮助。
============================ Firestore 文档包含此信息。
https://firebase.google.com/docs/firestore/query-data/listen “初始状态可以直接来自服务器,也可以来自本地缓存。如果本地缓存中有可用的状态,则查询快照将首先用缓存的数据填充,然后在客户端更新时用服务器的数据进行更新。赶上了服务器的状态。”
============
但是,当我刷新并检查 Firestore 控制台中的读取情况时,它仍在从服务器读取。
怎么了?
我做错了什么吗?
还是寻找其他服务更好?
从Flutter的StreamBuilder读取到Firestore时,缓存优先吗?还是服务器优先?
这与 StreamBuilder 无关,而是与如何从 Firestore 读取数据有关。当您调用 get() 时,在线时,您将始终从服务器读取数据,离线时,您将始终从缓存中读取数据。另请注意,当您连接到 Firebase 服务器时,无法强制从缓存中检索数据。
另一方面,如果你正在监听实时更新,那么你会有不同的行为,当你在线时,你总是先从缓存中读取数据,然后客户端 SDK 会尝试从服务器读取数据以查看设备离线时是否发生了变化。
还要记住,Flutter 中的 StreamBuilder 只是一个
Widget
,用于监听数据流并在流发出新数据时重建其 Widget
子树。