La migración de Google Fit a Health Connect implica reemplazar cada llamada a la API de Fit en tu app Capacitor por Health Connect en Android, y por HealthKit en iOS si también publicas ahí. Google dejó de aceptar nuevos registros en Fit el 1 de mayo de 2024 y da soporte a las APIs de Fit solo hasta finales de 2026. Esta guía mapea los tipos de datos y las llamadas de Fit a Health Connect, muestra el reemplazo code con @capgo/capacitor-health, y cubre la revisión de Play Console que conllevan los permisos de salud.
Cronograma de descontinuación de Google Fit
| Fecha | Qué sucedió |
|---|---|
| 1 de mayo de 2024 | No new developer sign-ups for Google Fit APIs |
| 2024 a 2026 | Las integraciones existentes de Fit siguen funcionando; Google dirige a los desarrolladores a Health Connect |
| 2026 | Las APIs de Fit, incluida la REST API, quedan descontinuadas |
| Final de 2026 | Fin del soporte. Google no ha publicado un día exacto de cierre |
La FAQ de migración de Google dice que no hay alternativa a la API REST de Fit con la misma forma: las apps en el dispositivo pasan a Health Connect y las integraciones en la nube pasan a la API de Google Health basada en cuenta. Si ves una fecha de cierre exacta citada en algún sitio, compruébala con la propia FAQ de Google antes de planificar en base a ella.
Qué cambia al pasar a Health Connect
| Google Fit | Health Connect | |
|---|---|---|
| Dónde residen los datos | Cuenta de Google, en la nube | En el dispositivo |
| Auth | OAuth 2.0 con scopes de fitness, Google Sign-In | Permisos de runtime de Android por tipo de datos |
| Configuración | Proyecto de Cloud, cliente OAuth, huellas SHA-1 | Permisos del manifiesto, pantalla de política de privacidad |
| Disponibilidad | Cualquier dispositivo Android con Play services | Integrado en Android 14+, una app de Google Play en versiones anteriores |
| Historial | Historial completo de la cuenta | Últimos 30 días por defecto, datos anteriores con READ_HEALTH_DATA_HISTORY |
| Acceso web/servidor | REST API | Ninguno (usa Google Health API para la nube) |
| iOS | No soportado | No compatible, usa HealthKit |
| Revisión de la tienda | Verificación de OAuth para scopes sensibles | Declaración de Health Connect en Play Console |
El mayor cambio es el modelo centrado en el dispositivo. Los datos de Health Connect en un teléfono no son visibles en otro. Si tu app muestra historial entre dispositivos, sincroniza las lecturas con tu propio backend.
Mapear tipos de datos de Fit a Health Connect
| Tipo de dato de Google Fit | Registro de Health Connect | @capgo/capacitor-health tipo |
|---|---|---|
com.google.step_count.delta |
StepsRecord |
steps |
com.google.distance.delta |
DistanceRecord |
distance |
com.google.calories.expended |
TotalCaloriesBurnedRecord / ActiveCaloriesBurnedRecord |
totalCalories / calories |
com.google.calories.bmr |
BasalMetabolicRateRecord |
basalCalories |
com.google.heart_rate.bpm |
HeartRateRecord |
heartRate |
com.google.weight |
WeightRecord |
weight |
com.google.height |
HeightRecord |
height |
com.google.body.fat.percentage |
BodyFatRecord |
bodyFat |
com.google.sleep.segment |
SleepSessionRecord con etapas |
sleep |
com.google.oxygen_saturation |
OxygenSaturationRecord |
oxygenSaturation |
com.google.blood_pressure |
BloodPressureRecord |
bloodPressure |
com.google.blood_glucose |
BloodGlucoseRecord |
bloodGlucose |
com.google.body.temperature |
BodyTemperatureRecord |
bodyTemperature |
com.google.hydration |
HydrationRecord |
dietaryWater |
com.google.nutrition |
NutritionRecord |
dietaryEnergyConsumed (solo energía) |
com.google.activity.segment y Sesiones API |
ExerciseSessionRecord |
workouts (leído mediante queryWorkouts) |
Tipos de Fit sin equivalente directo
- Puntos de corazón (
com.google.heart_minutes) y Minutos de movimiento (com.google.active_minutes) eran puntuaciones de Google Fit. Health Connect almacena datos brutos, no estas puntuaciones. Recalcula tu propia métrica a partir de la frecuencia cardíaca y las sesiones de ejercicio. - Muestras de actividad con tipos de actividad por segundo se reemplazan por sesiones de ejercicio con segmentos.
- Muestras de ubicación dentro de los entrenamientos pasan a ser
ExerciseRoutedatos en Health Connect, que necesitan un permiso aparte y el plugin no expone. - Cadencia, velocidad y potencia existen en Health Connect (
StepsCadenceRecord,SpeedRecord,PowerRecord) pero los tipos del plugin no los cubren. Si dependes de ellos, un pequeño método nativo personalizado es la vía más rápida.
Audita antes de escribir code: lista cada DataType y cada API que invoques (History, Recording, Sessions, Sensors, Config, REST), y marca cada uno como mapeado, recomputado o descartado.
Paso 1: Eliminar Google Fit
Elimina la integración de Fit de tu proyecto de Android y de JavaScript:
- Eliminar
com.google.android.gms:play-services-fitnessy, si solo se usa para Fit,play-services-authde losbuild.gradle. - Elimina el cliente OAuth de Fit de Google Cloud y los scopes de fitness de tu pantalla de consentimiento.
- Desinstala el antiguo plugin de la comunidad de Google Fit Capacitor que usabas y luego ejecuta
bunx cap sync.
Mantén el Fit code en una rama hasta que la nueva versión esté en producción, para poder exportar datos históricos si los usuarios lo solicitan.
Paso 2: Instala el plugin de salud
bun add @capgo/capacitor-health
bunx cap sync
@capgo/capacitor-health soporta Capacitor 8, usa Health Connect en Android y HealthKit en iOS, y requiere Android minSdk 26.
Configuración de Android
El plugin integra los permisos de lectura y escritura de Health Connect para los tipos compatibles en tu manifest, además de la <queries> entrada para el paquete de Health Connect y la actividad de justificación de permisos. Debes:
- Proporcionar una política de privacidad. Health Connect la abre desde la hoja de permisos. Puedes añadir
android/app/src/main/assets/public/privacypolicy.html, o configurar una URL enandroid/app/src/main/res/values/strings.xml:
<string name="health_connect_privacy_policy_url">https://example.com/privacy</string>
- Reduce los permisos. Google Play revisa cada permiso de Health Connect que declares. Si solo lees pasos y ritmo cardíaco, elimina el resto con
tools:node="remove":
<uses-permission
android:name="android.permission.health.WRITE_BLOOD_GLUCOSE"
tools:node="remove" />
- Añade acceso al historial si lo necesitas. Health Connect limita las lecturas a unos 30 días, a menos que el usuario conceda
READ_HEALTH_DATA_HISTORY:
<uses-permission android:name="android.permission.health.READ_HEALTH_DATA_HISTORY" />
Configurar iOS
Habilita la capacidad HealthKit en Xcode y añade las cadenas de uso en Info.plist:
<key>NSHealthShareUsageDescription</key>
<string>Show your steps and workouts in the app.</string>
<key>NSHealthUpdateUsageDescription</key>
<string>Save the workouts you record in the app.</string>
Paso 3: Verificar disponibilidad
Google Fit funcionaba en cualquier lugar donde existieran Play services. Health Connect puede no estar disponible en Android 13 o versiones anteriores, o requerir una actualización.
import { Health } from '@capgo/capacitor-health';
export async function ensureHealthAvailable() {
const result = await Health.isAvailable();
if (result.available) return true;
// On Android, send the user to install or update Health Connect
if (result.platform === 'android') {
await Health.openHealthConnectSettings();
}
console.warn('Health store unavailable:', result.reason);
return false;
}
Muestra una pantalla de explicación breve antes de redirigir. Los usuarios que no conocen Health Connect se confunden cuando se abre la Play Store sin previo aviso.
Paso 4: Reemplazar OAuth con permisos
El flujo de Fit era: Google Sign-In, solicitar scopes de fitness y luego llamar a las APIs. El nuevo flujo es una sola hoja de permisos:
const status = await Health.requestAuthorization({
read: ['steps', 'distance', 'calories', 'heartRate', 'sleep', 'workouts'],
write: ['weight'],
requestHistoryAccess: true, // Android only
});
if (status.readDenied.length > 0) {
// explain what will not work and offer openHealthConnectSettings()
}
if (status.historyAccessAvailable === false) {
// provider too old: only the last 30 days are readable
}
Los permisos son por tipo de dato y el usuario puede conceder cualquier subconjunto. Usa checkAuthorization con las mismas opciones en cada inicio de la app, porque los usuarios pueden revocar el acceso en la configuración de Health Connect en cualquier momento. En iOS, HealthKit oculta las denegaciones de lectura por privacidad, por lo que un resultado vacío puede significar «sin datos» o «sin acceso».
Paso 5: Reemplazar lecturas de History API
Un Fit readData la llamada a muestras crudas se convierte en readSamples:
const end = new Date();
const start = new Date(end.getTime() - 24 * 60 * 60 * 1000);
const { samples } = await Health.readSamples({
dataType: 'heartRate',
startDate: start.toISOString(),
endDate: end.toISOString(),
limit: 500,
ascending: true,
});
for (const s of samples) {
console.log(s.startDate, s.value, s.unit, s.sourceName, s.deviceType);
}
sourceName y, en Android, deviceType (watch, phone, chestStrap, y así sucesivamente) reemplazan los objetos de fuente de datos de Fit. Úsalos para priorizar los datos del reloj sobre los del teléfono cuando ambos existan.
Paso 6: Reemplazar lecturas por bucket y agregadas
de Fit bucketByTime además de aggregate pasa a ser queryAggregated:
const { samples: daily } = await Health.queryAggregated({
dataType: 'steps',
startDate: new Date(Date.now() - 7 * 86_400_000).toISOString(),
endDate: new Date().toISOString(),
bucket: 'day', // 'hour' | 'day' | 'week' | 'month'
aggregation: 'sum',
});
const { samples: hr } = await Health.queryAggregated({
dataType: 'heartRate',
bucket: 'hour',
aggregation: ['min', 'average', 'max'],
startDate: new Date(Date.now() - 86_400_000).toISOString(),
endDate: new Date().toISOString(),
});
// hr[i].values.min, hr[i].values.average, hr[i].values.max
Agrega siempre los pasos en lugar de sumar muestras sin procesar. Health Connect deduplica los datos solapados de varias apps durante la agregación, y las sumas sin procesar suelen contar doble cuando un reloj y un teléfono registran pasos.
Paso 7: Reemplazar API de Sessions
Las sesiones de Fit se mapean a sesiones de ejercicio:
const { workouts, anchor } = await Health.queryWorkouts({
workoutType: 'running',
startDate: new Date(Date.now() - 30 * 86_400_000).toISOString(),
endDate: new Date().toISOString(),
limit: 50,
});
for (const w of workouts) {
console.log(w.workoutType, w.duration, w.totalDistance, w.totalEnergyBurned);
}
// pass `anchor` back to fetch the next page
Solicitud workouts en read permisos primero. El plugin lee entrenamientos pero no escribe sesiones de ejercicio, por lo que si tu app registra entrenamientos, escribe las muestras subyacentes (distancia, calorías, frecuencia cardíaca) y guarda la sesión en tu backend, o añade un método nativo para ExerciseSessionRecord.
Paso 8: Reemplazar los inserts
de Fit insertData pasa a ser saveSample:
await Health.saveSample({
dataType: 'weight',
value: 72.4, // kilograms
startDate: new Date().toISOString(),
});
await Health.saveSample({
dataType: 'bloodPressure',
value: 120,
systolic: 120,
diastolic: 80,
startDate: new Date().toISOString(),
});
Los valores deben usar la unidad por defecto de cada tipo (kilogramos, metros, kilocalorías, bpm). La metadata opción es ignorada por Health Connect.
Paso 9: Superar la revisión de Google Play
Los permisos de salud activan una revisión adicional:
- En Play Console, abre Contenido de la app y completa la declaración de Apps de salud y el formulario de permisos de Health Connect. Justifica cada permiso que solicites.
- Asegúrate de que la política de privacidad en Play Console y la que se muestra en la hoja de Health Connect describan el uso de los datos de salud.
- Actualiza el Data safety formulario: datos de salud y fitness, recopilados o no, compartidos o no.
- Envía un build que solo declare los permisos que justificaste. Los permisos extra declarados son el motivo de rechazo más común.
Planifica que la revisión tarde más de lo habitual. Lanza la migración como un release independiente, sin mezclarla con otras features.
Paso 10: Migrar las expectativas del usuario
- Informa a los usuarios que su historial ahora proviene de Health Connect, y que los datos antiguos podrían limitarse a 30 días hasta que concedan acceso al historial.
- Si tu app usaba Fit para la sincronización en la nube, traslada esa responsabilidad a tu backend ahora.
- Elimina los botones “Connect Google Fit” y renómbralos a “Connect Health Connect” en Android y “Connect Apple Health” en iOS.
Solución de problemas
isAvailable() devuelve false en Android 13: Health Connect no está instalado o está desactualizado. Llama a openHealthConnectSettings().
El prompt de permisos nunca aparece: el permiso no está declarado en el manifiesto fusionado o lo eliminaste con tools:node="remove". Revisa android/app/build/intermediates/merged_manifests.
Las lecturas solo devuelven 30 días: solicitud requestHistoryAccess: true y declara READ_HEALTH_DATA_HISTORY.
Los totales de pasos son mayores que en Google Fit: sumaste muestras sin procesar. Usa queryAggregated.
Resultados vacíos en iOS: no hay datos o se denegó el permiso de lectura. HealthKit no especifica cuál.
Play Console rechaza la actualización: elimina los permisos de Health Connect no declarados o injustificados y vuelve a enviarla con una justificación clara.
Lanza la migración por etapas
La parte nativa (plugin, manifest, capability de HealthKit) requiere un release en la tienda. Después, las queries, la UI y el mapeo de datos son JavaScript, sobre los que puedes iterar con actualizaciones Live Update de Capgo mientras los usuarios prueban el nuevo flujo. Si también lees datos de sensores en tiempo real, consulta nuestra guía para crear un monitor de frecuencia cardíaca con Capacitor, y la documentación del plugin de salud para cada tipo de dato.