Expo Health Connect, from phone to backend
Expo Health Connect needs a native Android development build rather than Expo Go. HC Sync supplies a config plugin and TypeScript wrapper to upload permitted records to your backend. The example uses minSdk 26 and compileSdkVersion 36. Choose explicit plugin types and request matching runtime permissions before syncing from a user action.
Last updated: 2026-11-04. Source for the 2026 service details: HC Sync page details.
Which Expo build supports Health Connect?
Health Connect is not available inside Expo Go. Use an Android development client or an EAS build with the native Health Connect bridge installed. The React Native installation guide lists the package archive, peer dependencies and build settings. Installing an npm package alone cannot add a native module to an already installed Expo Go application.
Rebuild the app whenever you change native permissions or plugins. A JavaScript update does not rewrite AndroidManifest.xml. Test the build on an Android phone with Health Connect available and with a source app that writes your chosen record types. Your backend can be written in any language; Expo only handles the phone side.
Which plugin types should you declare?
Merge these entries into the plugins array in your Expo app configuration. The HC Sync plugin requires an explicit non-empty types array. Missing types fail the build rather than silently requesting every supported permission. Steps and SleepSession are examples; remove any type your feature does not use.
"plugins": [
"react-native-health-connect",
["expo-build-properties", { "android": { "compileSdkVersion": 36, "targetSdkVersion": 36, "minSdkVersion": 26 } }],
["hcsync-react-native", { "types": ["Steps", "SleepSession"] }]
]The plugin adds selected read permissions, the Health Connect package query, the permissions rationale action and the Android permission usage alias. Its default activity is .MainActivity; set activity if your application uses a different one. These manifest declarations do not replace runtime permission requests or your own explanation of why health data leaves the phone.
How do you connect from a user action?
First mint a scoped user token on your authenticated server with POST /v1/user-tokens. Keep the secret key there and pass the token to the correct signed-in user. Then use the same type list in your runtime code:
import { connectHealth, syncHealthOnce, resetHealthSync } from "hcsync-react-native";
const types = ["Steps", "SleepSession"] as const;
// After your own explicit consent screen, from a user action:
if (await connectHealth(types)) {
await syncHealthOnce(userToken, types); // token returned by your authenticated backend
}
// On logout:
await resetHealthSync(userToken);Wire syncHealthOnce into foreground app lifecycle events after consent. The wrapper uploads changes in batches and remembers sync positions. It does not schedule background work on its own. Do not promise a continuously live dashboard when the app is closed: source apps, permissions and foreground execution all affect freshness.
What should you verify before release?
Check the merged manifest after prebuild and confirm that it contains only your selected health permissions. Deny one permission during testing and make sure your interface still works. Test logout and account switching so one user's token never reaches another user's flow. Use GET /v1/users and the dashboard to inspect last sync, then read raw records or summaries from your backend.
How do you verify the full integration?
Create a free project and save the secret key, read key, webhook secret and recovery code somewhere secure. The secret key belongs on your backend. A user token authorizes writes for one user; it is not a credential for reading records. Your own authenticated endpoint must select the user id from the signed-in session rather than accepting an arbitrary id from the app.
Start with sample data to test server reads without a phone. The sample user proves that your API credentials and parsing work; it does not prove Health Connect permissions or a device integration. Next test a real Android phone, grant only the permissions your feature uses, and confirm that a source app actually wrote those records into Health Connect. An empty response can mean no source data, denied permission, an incorrect user id or a time window that misses the records.
How should you handle consent, deletion and operations?
Before uploading health data, show a separate explicit consent choice with an unticked control, your purpose, the requested data types, US storage through HC Sync, and a way to withdraw. Android permission approval alone does not explain your server processing. Match your privacy notice and Play declarations to the actual types you collect. The consent and publishing checklist gives sample copy to adapt.
Keep your own downstream storage consistent with deletion events. Deleting a user with the secret-key API removes their server records and revokes existing device tokens. Stop local sync on withdrawal as well. Reads expose current records, not a permanent history of deletions. Webhook delivery can fail, so monitor attempts in the dashboard, retain event ids for deduplication, and handle retries without duplicating side effects. The API documentation describes queue limits and replay.
What are the common integration questions?
Can Expo Go read Health Connect?
No. Build a native Android development client containing the Health Connect module.
Can I omit plugin types?
No. Supply an explicit non-empty types array and use the same selection at runtime.
React Native Health Connect backend · Expo Health Connect · Health Connect Python · Health Connect REST API
How do I delete a user’s data?
DELETE /v1/users/{id} removes everything for that user immediately.