-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
working on dexcom sync in background fetch
- Loading branch information
1 parent
b94b05f
commit d239949
Showing
6 changed files
with
194 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import { View } from "react-native"; | ||
import * as BackgroundFetch from "expo-background-fetch"; | ||
import * as Notifications from "expo-notifications"; | ||
import * as TaskManager from "expo-task-manager"; | ||
|
||
import { Button } from "~/components/ui/button"; | ||
import { Text } from "~/components/ui/text"; | ||
import { useDexcomSync } from "~/hooks/use-dexcom-sync"; | ||
import { BACKGROUND_FETCH_DEXCOM_SYNC } from "~/lib/constants"; | ||
import { useGlucoseStore } from "~/stores/glucose-store"; | ||
|
||
const BACKGROUND_FETCH_TASK = "background-fetch"; | ||
|
||
// 1. Define the task by providing a name and the function that should be executed | ||
// Note: This needs to be called in the global scope (e.g outside of your React components) | ||
TaskManager.defineTask(BACKGROUND_FETCH_TASK, async () => { | ||
const { lastSyncedTime } = useGlucoseStore(); | ||
|
||
try { | ||
const result = await performSync(lastSyncedTime); | ||
|
||
if (result.newData) { | ||
await Notifications.scheduleNotificationAsync({ | ||
content: { | ||
title: "New CGM Data Available", | ||
body: "Tap to view your latest glucose readings.", | ||
}, | ||
trigger: null, | ||
}); | ||
return BackgroundFetch.BackgroundFetchResult.NewData; | ||
} else { | ||
return BackgroundFetch.BackgroundFetchResult.NoData; | ||
} | ||
} catch (error) { | ||
console.error("Background sync failed:", error); | ||
return BackgroundFetch.BackgroundFetchResult.Failed; | ||
} | ||
}); | ||
|
||
export function DexcomBackgroundSync() { | ||
const { status, syncNow, isPending, isRegistered, toggleFetchTask } = | ||
useDexcomSync(); | ||
|
||
return ( | ||
<View className="flex-1 items-center justify-center"> | ||
<View className="mb-5"> | ||
<Text className="text-base"> | ||
Background fetch status:{" "} | ||
<Text className="font-bold"> | ||
{status !== null | ||
? BackgroundFetch.BackgroundFetchStatus[status] | ||
: "Unknown"} | ||
</Text> | ||
</Text> | ||
<Text className="mt-2 text-base"> | ||
Background fetch task name:{" "} | ||
<Text className="font-bold"> | ||
{isRegistered | ||
? BACKGROUND_FETCH_DEXCOM_SYNC | ||
: "Not registered yet!"} | ||
</Text> | ||
</Text> | ||
</View> | ||
<View className="w-4/5"> | ||
<Button onPress={toggleFetchTask}> | ||
<Text> | ||
{isRegistered | ||
? "Unregister BackgroundFetch task" | ||
: "Register BackgroundFetch task"} | ||
</Text> | ||
</Button> | ||
<View className="h-4" /> | ||
<Button onPress={syncNow} disabled={isPending}> | ||
<Text>{isPending ? "Syncing..." : "Sync Now"}</Text> | ||
</Button> | ||
</View> | ||
</View> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
import { useCallback, useEffect, useState } from "react"; | ||
import * as BackgroundFetch from "expo-background-fetch"; | ||
import * as TaskManager from "expo-task-manager"; | ||
import { DateTime } from "luxon"; | ||
|
||
import { BACKGROUND_FETCH_DEXCOM_SYNC } from "~/lib/constants"; | ||
import { useGlucoseStore } from "~/stores/glucose-store"; | ||
import { api } from "~/utils/api"; | ||
|
||
// 2. Register the task at some point in your app by providing the same name, | ||
// and some configuration options for how the background fetch should behave | ||
// Note: This does NOT need to be in the global scope and CAN be used in your React components! | ||
export async function registerBackgroundFetchAsync() { | ||
try { | ||
await BackgroundFetch.registerTaskAsync(BACKGROUND_FETCH_DEXCOM_SYNC, { | ||
minimumInterval: 15 * 60, // 15 minutes | ||
stopOnTerminate: false, // android only | ||
startOnBoot: true, // android only | ||
}); | ||
await BackgroundFetch.setMinimumIntervalAsync(15 * 60); // 15 minutes, iOS minimum | ||
console.log("Background fetch registered"); | ||
} catch (err) { | ||
console.log("Background fetch failed to register", err); | ||
} | ||
} | ||
|
||
// 3. (Optional) Unregister tasks by specifying the task name | ||
// This will cancel any future background fetch calls that match the given name | ||
// Note: This does NOT need to be in the global scope and CAN be used in your React components! | ||
export async function unregisterBackgroundFetchAsync() { | ||
return BackgroundFetch.unregisterTaskAsync(BACKGROUND_FETCH_DEXCOM_SYNC); | ||
} | ||
|
||
export function useDexcomSync() { | ||
const { lastSyncedTime, setLastSyncedTime } = useGlucoseStore(); | ||
const [status, setStatus] = | ||
useState<BackgroundFetch.BackgroundFetchStatus | null>(null); | ||
const [isRegistered, setIsRegistered] = useState(false); | ||
|
||
const fetchDataRangeQuery = api.dexcom.fetchDataRange.useQuery({ | ||
lastSyncTime: lastSyncedTime ?? undefined, | ||
}); | ||
const fetchAndStoreEGVsMutation = api.dexcom.fetchAndStoreEGVs.useMutation(); | ||
|
||
useEffect(() => { | ||
void checkStatusAsync(); | ||
}, []); | ||
|
||
const checkStatusAsync = async () => { | ||
const fetchStatus = await BackgroundFetch.getStatusAsync(); | ||
const isTaskRegistered = await TaskManager.isTaskRegisteredAsync( | ||
BACKGROUND_FETCH_DEXCOM_SYNC, | ||
); | ||
setStatus(fetchStatus); | ||
setIsRegistered(isTaskRegistered); | ||
}; | ||
|
||
const toggleFetchTask = async () => { | ||
if (isRegistered) { | ||
await unregisterBackgroundFetchAsync(); | ||
} else { | ||
await registerBackgroundFetchAsync(); | ||
} | ||
await checkStatusAsync(); | ||
}; | ||
|
||
const syncNow = useCallback(async () => { | ||
try { | ||
if (fetchDataRangeQuery.data?.egvs) { | ||
const startDate = DateTime.fromISO( | ||
fetchDataRangeQuery.data.egvs.start.systemTime, | ||
{ zone: "utc" }, | ||
); | ||
const endDate = DateTime.fromISO( | ||
fetchDataRangeQuery.data.egvs.end.systemTime, | ||
{ zone: "utc" }, | ||
); | ||
|
||
const result = await fetchAndStoreEGVsMutation.mutateAsync({ | ||
startDate: startDate.toISO() ?? "", | ||
endDate: endDate.toISO() ?? "", | ||
}); | ||
|
||
if (result.recordsInserted > 0 && result.latestEGVTimestamp) { | ||
setLastSyncedTime( | ||
DateTime.fromISO(result.latestEGVTimestamp, { zone: "utc" }), | ||
); | ||
console.log("New data synced"); | ||
} else { | ||
console.log("No new data available"); | ||
} | ||
} | ||
} catch (error) { | ||
console.error("Sync failed", error); | ||
} | ||
}, [ | ||
fetchDataRangeQuery.data?.egvs, | ||
fetchAndStoreEGVsMutation, | ||
setLastSyncedTime, | ||
]); | ||
|
||
return { | ||
syncNow, | ||
status, | ||
isRegistered, | ||
toggleFetchTask, | ||
isPending: | ||
fetchDataRangeQuery.isPending || fetchAndStoreEGVsMutation.isPending, | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters