Skip to content
GUIDE · UNIFIED WORKFLOW

Sync and aggregation

Health Connector supports both direct queries and durable incremental data flows.

Aggregate data

Aggregation requests are created by a data type, which keeps the result unit aligned with the source records.

dart
final totalSteps = await connector.aggregate(
  HealthDataType.steps.aggregateSum(
    startTime: start,
    endTime: end,
  ),
);

final averageHeartRate = await connector.aggregate(
  HealthDataType.heartRate.aggregateAvg(
    startTime: start,
    endTime: end,
  ),
);

Only operations supported by a data type are exposed. Depending on the record, the SDK can provide sum, average, minimum, or maximum metrics.

Incremental synchronization

Use sync tokens when an application maintains a local projection of the health store. The first request establishes a cursor; later requests return changes since that cursor.

The durable loop is:

  1. Load the last committed token for the user and data type.
  2. Request changes with that token, or null for the first run.
  3. Apply inserted, updated, and deleted records in one local transaction.
  4. Persist the returned token only after the local transaction succeeds.
  5. Continue while the response reports more pages.

Commit data and cursor together

Persisting a new cursor before local data is durable can permanently skip records. Treat the record changes and next token as one transaction.

Recovery

A token can expire or become invalid. Handle HealthConnectorErrorCode.invalidArgument by discarding the old cursor and rebuilding the local projection from a fresh sync.

Transient service failures such as rateLimitExceeded, remoteError, or dataSyncInProgress should use bounded exponential backoff.

Background work

Background access depends on platform capability, permission, and operating-system scheduling. Check HealthPlatformFeature.readHealthDataInBackground before enabling background sync and design foreground reconciliation as the reliable fallback.

Released under the Apache 2.0 License.