Flutter Amplify DataStore如何获取待同步记录总数?
实现Flutter Amplify DataStore首次同步进度指示器的方案
由于Amplify DataStore本身未提供直接获取待同步记录总数的API,我们可以通过主动查询云端记录总数 + 监听同步事件累加已同步数的方式实现精准进度显示,具体步骤如下:
1. 查询云端各模型的总记录数
通过Amplify GraphQL API的count查询,获取每个待同步模型在云端的总记录数,累加得到首次同步的总数据量。
示例代码:获取云端总记录数
Future<int> fetchTotalCloudRecords() async { // 并行查询所有需要同步的模型总数 final futures = [ // 查询Device模型总数 Amplify.API.query( request: GraphQLRequest<String>( document: ''' query CountDevices { countDevices { count } } ''', ), ), // 若有其他模型,添加对应的count查询 Amplify.API.query( request: GraphQLRequest<String>( document: ''' query CountOtherModels { countOtherModels { count } } ''', ), ), ]; final results = await Future.wait(futures); // 解析并累加各模型总数 int total = 0; for (final result in results) { final data = result.data as Map; final countKey = data.keys.first; total += int.parse(data[countKey]['count'].toString()); } return total; }
注意:需确保Amplify API已为模型生成count查询(默认@model类型会自动生成),且用户IAM权限允许执行count操作。
2. 监听DataStore同步事件,计算进度
在启动DataStore同步前先获取云端总记录数,然后监听modelSynced事件,累加已同步的记录数(added + updated),实时计算进度百分比并更新UI。
示例代码:同步进度监听
int _totalSyncRecords = 0; int _syncedRecords = 0; late StreamSubscription<HubEvent> _hubSubscription; double _syncProgress = 0.0; void initSyncProgressTracking() async { // 先获取云端总记录数 _totalSyncRecords = await fetchTotalCloudRecords(); _hubSubscription = Amplify.Hub.listen([HubChannel.DataStore], (msg) { switch (msg.eventName) { case "ready": getAllDevicesInDataStore().then((_) => _hubSubscription.cancel()); break; case "modelSynced": final payload = msg.payload as ModelSyncedEvent; // 仅处理首次全量同步(非增量同步) if (!payload.isDeltaSync) { // 累加已同步的新增/更新记录数 _syncedRecords += payload.added + payload.updated; // 计算进度(避免除以0) _syncProgress = _totalSyncRecords > 0 ? _syncedRecords / _totalSyncRecords : 1.0; // 更新UI进度指示器 setState(() {}); } if (kDebugMode) { print('同步模型: ${payload.modelName}, 增量同步? ${payload.isDeltaSync}'); print('新增: ${payload.added}, 更新: ${payload.updated}, 删除: ${payload.deleted}'); } break; } }); }
3. UI层面实现进度指示器
在UI中使用LinearProgressIndicator或自定义进度组件,绑定计算出的进度值:
@override Widget build(BuildContext context) { return Scaffold( body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text('同步进度: ${(_syncProgress * 100).toStringAsFixed(1)}%'), const SizedBox(height: 16), LinearProgressIndicator(value: _syncProgress), ], ), ), ); }
注意事项
- 若云端数据在查询总数后到同步开始前发生变更,进度可能存在微小误差,但对于用户体验而言可忽略。
- 若模型包含关联数据,需根据业务场景决定是否将关联记录计入总数(例如查询主模型时同时统计关联子模型的数量)。
内容的提问来源于stack exchange,提问作者Adam T
相关产品推荐
相关产品推荐

