我有一个 Flutter 小部件,可以监听 2 个 Firestore 查询:
class ExampleWidget extends StatefulWidget {
const ExampleWidget({super.key});
@override
State<ExampleWidget> createState() => _ExampleWidgetState();
}
class _ExampleWidgetState extends State<ExampleWidget> {
@override
void initState() {
FirebaseFirestore.instance
.collection('items')
.where('tags', arrayContains: 'foo')
.snapshots()
.listen(
(items) => print('Got items from query 1: ${items.docs.length}'));
FirebaseFirestore.instance
.collection('items')
.snapshots()
.listen(
(items) => print('Got items from query 2: ${items.docs.length}'));
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(body: Center(child: Text('Example')));
}
}
小部件直接在
main.dart
文件中渲染:
Future<void> main() async {
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
FirebaseFirestore.instance.useFirestoreEmulator('localhost', 8080);
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(primarySwatch: Colors.blue),
home: ExampleWidget(),
);
}
}
以下是文件:
items:
item#1:
tags: ['foo']
item#2:
tags: ['foo']
item#3:
tags: ['bar']
当我在生产中运行应用程序时,我看到以下日志:
Got items from query 1: 2
Got items from query 2: 3
当我使用 Firebase 模拟器运行应用程序时,我看到以下日志:
Got items from query 1: 2
Got items from query 2: 2
Got items from query 2: 3
我期望每个查询都能准确地接收 2 个和 3 个匹配项的一个事件(就像在产品中运行时一样)。为什么第二个查询的监听器执行了两次?
第二个查询收到重复响应的原因是 Firestore 本地缓存:第一个查询的结果保存在本地,并在实际结果从服务器到达之前用作第二个查询的第一个数据源。模拟器和生产环境之间的行为不同的原因是延迟,以下是每个事件的事件顺序:
Emulator:
1. query 1 is executed
2. result from query 1 is received (2) immediately and saved into cache
3. query 2 is executed
4. query 2 uses the result from cache (2)
5. query 2 receives the correct result (3) from the server
Production:
1. query 1 is executed
3. query 2 is executed
4. result from query 1 is received (2) and saved into cache
5. result from query 2 is received (3) and saved into cache
更多信息可以在 flutterfire 和 firebase-js-sdk 存储库中的这些 GH 问题中找到: