From 81632a4275aed1c19f833361577ba8a7a8128ff0 Mon Sep 17 00:00:00 2001 From: Marcus Rehbock Date: Sat, 8 Aug 2026 00:03:17 -0700 Subject: [PATCH] Fix: Fitbit screen showed no data after a successful sync MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit load() caches by endpoint for the session, so the post-sync refresh re-served the pre-sync (empty) summary. Sync now invalidates the fitbit cache keys — the watermark before reading, summary+latest after uploading — so the refetch actually hits the server. Co-Authored-By: Claude Fable 5 --- src/lib/api.tsx | 5 +++++ src/lib/fitbit.ts | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/lib/api.tsx b/src/lib/api.tsx index eed9fd3..d3b2976 100644 --- a/src/lib/api.tsx +++ b/src/lib/api.tsx @@ -98,6 +98,11 @@ export function clearCache() { cache = {}; } +/* drop specific endpoints from the cache so the next load() refetches */ +export function invalidate(...keys: EpKey[]) { + for (const k of keys) delete cache[k]; +} + /* ---- auth context ---- */ interface AuthCtx { diff --git a/src/lib/fitbit.ts b/src/lib/fitbit.ts index d50d187..86cd20f 100644 --- a/src/lib/fitbit.ts +++ b/src/lib/fitbit.ts @@ -2,7 +2,7 @@ Android-only: react-native-health-connect is loaded lazily so the module's absence (iOS, Expo Go) never crashes the app. */ import { Platform } from 'react-native'; -import { FITBIT_SYNC_URL, load, postJson } from './api'; +import { FITBIT_SYNC_URL, invalidate, load, postJson } from './api'; export interface SyncResult { ok: boolean; @@ -90,6 +90,7 @@ export async function syncFitbit(onProgress?: (msg: string) => void): Promise ({ accessType: 'read', recordType: r }))); say('Checking server watermark…'); + invalidate('fitbitLatest'); // watermark must be fresh, never the session-cached copy const latest = await load<{ samples: Record; daily: Record; @@ -182,6 +183,9 @@ export async function syncFitbit(onProgress?: (msg: string) => void): Promise