Flutter如何编写异步代码:等待Firestore保存完成后刷新UI
实现方案
1 调整savetoremote_dynamic方法返回值
首先要确保数据保存方法返回Future类型,Firestore的写入操作本身原生返回Future,只需修改方法定义即可:
// 将原有的void返回值改为Future<void>,添加async标识 Future<void> savetoremote_dynamic(BuildContext context) async { // 原有Firestore写入逻辑,在写入操作前加await,比如: await FirebaseFirestore.instance .collection("你的集合名") .doc("你的文档ID") .set(UserManager.userdata); // 方法无需额外return,异步操作完成后Future会自动进入完成状态 }
2 改造validate方法添加等待逻辑
给validate方法添加async标识,等待数据保存完成后再执行Widget重建:
// 修改返回值为Future<void>,添加async标识 Future<void> validate() async { // Flutter新版本中currentState可能为空,需要加!判空 if (_formKey.currentState!.validate()) { UserManager.userdata["userStats"][0]["userActivity"] = userActivity; // 等待数据写入完成 await savetoremote_dynamic(context); // 写入完成后再重建页面 AppBuilder.of(context).rebuild(); } }
3 可选优化:增加异常处理和加载状态
为了避免写入失败导致逻辑异常,建议添加异常捕获,同时可搭配加载状态防止用户重复点击:
Future<void> validate() async { if (_formKey.currentState!.validate()) { // 开启加载状态,UI可对应展示加载动画 setState((){ _isLoading = true; }); try { UserManager.userdata["userStats"][0]["userActivity"] = userActivity; await savetoremote_dynamic(context); AppBuilder.of(context).rebuild(); } catch (e) { // 写入失败时给出用户提示 ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text("数据保存失败,请重试:${e.toString()}")) ); } finally { // 无论成功失败都关闭加载状态 setState((){ _isLoading = false; }); } } }
提示:如果你的计算逻辑依赖Firestore端生成的字段(比如服务端时间戳、云函数计算字段等),可以在
savetoremote_dynamic写入完成后,查询最新的文档数据更新到UserManager.userdata中再执行重建,避免本地数据和服务端数据不一致。
内容的提问来源于stack exchange,提问作者Dalon
相关产品推荐
相关产品推荐

