Bro*_*ure 2 firebase flutter google-cloud-firestore
这发生在我的主应用程序中,我使用给定的代码实验室复制它: https://codelabs.developers.google.com/codelabs/flutter-firebase/index.html ?index=..%2F..index#10
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Baby Names',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() {
return _MyHomePageState();
}
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Baby Name Votes')),
body: _buildBody(context),
);
}
Widget _buildBody(BuildContext context) {
return StreamBuilder<QuerySnapshot>(
stream: Firestore.instance.collection('baby').snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) return LinearProgressIndicator();
return _buildList(context, snapshot.data.documents);
},
);
}
Widget _buildList(BuildContext context, List<DocumentSnapshot> snapshot){
return ListView(
padding: const EdgeInsets.only(top: 20.0),
children: snapshot.map((data) => _buildListItem(context, data)).toList(),
);
}
Widget _buildListItem(BuildContext context, DocumentSnapshot data) {
final record = Record.fromSnapshot(data);
return Padding(
key: ValueKey(record.name),
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.circular(5.0),
),
child: ListTile(
title: Text(record.name),
trailing: Text(record.votes.toString()),
onTap: () => print(record),
),
),
);
}
}
class Record {
final String name;
final int votes;
final DocumentReference reference;
Record.fromMap(Map<String, dynamic> map, {this.reference})
: assert(map['name'] != null),
assert(map['votes'] != null),
name = map['name'],
votes = map['votes'];
Record.fromSnapshot(DocumentSnapshot snapshot)
: this.fromMap(snapshot.data, reference: snapshot.reference);
@override
String toString() => "Record<$name:$votes>";
}
Run Code Online (Sandbox Code Playgroud)
我唯一使用的插件是cloud_firestore 0.9.5+2。请您对这个测试过程保持耐心。您不会立即看到该问题。首先运行应用程序,设置该项目。您可以按照给定 Codelab 中的说明进行操作。一旦前端和后端的一切都设置完毕(在firstore上创建文档)。去吃午饭、吃晚饭、玩电子游戏或和朋友出去玩。1小时后回来。运行该应用程序,您将需要为那些新读取的内容产生费用。再做一次,1小时后回来,同样的事情还会发生
如何在现实生活中复制它:通过 Codelab 中的给定代码启动此应用程序。运行它,如果您将 4 个文档存储到 firestore 中,它应该会产生 4 个文档读取。
再次启动。不收取任何阅读费用。太棒了,它有效!但不,事实并非如此。
第二天我醒来,打开应用程序,我读了 4 次。好吧,也许发生了一些魔法。我立即重新启动它,并且没有产生任何费用(太棒了!)。1 小时后,我启动应用程序,并被收取 4 次读取费用,以显示完全没有更改的 4 个相同文档。
问题是,在应用程序启动时。它似乎正在从查询快照下载文档。文件没有发生任何变化。该流构建器之前已运行过多次。
离线模式(飞行模式),缓存数据显示没有问题。
例如,在我的主应用程序中,我有一个 photoUrl,在新的应用程序启动时,您可以看到它从 firestore 加载(意味着作为新文档下载,从而产生读取费用)。我重新启动我的主应用程序,不收取任何费用,并且照片不刷新(太棒了!)。1 小时后,我启动应用程序,并对我检索的每个文档进行收费(没有更改)。
这是 cloud firestore 应该表现的方式吗? 根据我所读到的内容,它不应该像这样:(
build()除了构建小部件树之外,您不应该做实际的工作
而不是在构建中这样的代码
stream: Firestore.instance.collection('baby').snapshots(),
Run Code Online (Sandbox Code Playgroud)
你应该使用
Stream<Snapshot> babyStream;
@override
void initState() {
super.initState();
babyStream = Firestore.instance.collection('baby').snapshots();
}
Widget _buildBody(BuildContext context) {
return StreamBuilder<QuerySnapshot>(
stream: babyStream,
builder: (context, snapshot) {
if (!snapshot.hasData) return LinearProgressIndicator();
return _buildList(context, snapshot.data.documents);
},
);
}
Run Code Online (Sandbox Code Playgroud)
FutureBuilder 文档没有明确提到它,但它是一样的
https://docs.flutter.io/flutter/widgets/FutureBuilder-class.html
未来必须更早获得,例如在 State.initState、State.didUpdateConfig 或 State.didChangeDependencies 期间。在构造 FutureBuilder 时,它不能在 State.build 或 StatelessWidget.build 方法调用期间创建。如果future和FutureBuilder同时创建,那么每次重建FutureBuilder的parent时,异步任务都会重新启动。
| 归档时间: |
|
| 查看次数: |
2763 次 |
| 最近记录: |