Saltar al contenido principal

Migración de Google Fit a Health Connect en Capacitor

Migra una app de Capacitor de Google Fit a Health Connect antes de que las APIs de Fit terminen en 2026: mapeo de tipos de datos, permisos, queries y revisión de Play.

Migrar una app de fitness de Capacitor de Google Fit a Health Connect

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 ExerciseRoute datos 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-fitness y, si solo se usa para Fit, play-services-auth de los build.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:

  1. 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 en android/app/src/main/res/values/strings.xml:
<string name="health_connect_privacy_policy_url">https://example.com/privacy</string>
  1. 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" />
  1. 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:

  1. 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.
  2. 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.
  3. Actualiza el Data safety formulario: datos de salud y fitness, recopilados o no, compartidos o no.
  4. 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.

Live updates para apps Capacitor

Cuando un bug de la capa web está en producción, publica el fix a través de Capgo en lugar de esperar días a la aprobación de la app store. Los usuarios reciben la actualización en segundo plano mientras los cambios nativos siguen el flujo de revisión habitual.

Lo último de nuestro blog

Capgo te da la información clave que necesitas para crear una app móvil realmente profesional.