Skip to content

Commit

Permalink
clearProfilePushToken on logout
Browse files Browse the repository at this point in the history
  • Loading branch information
fjsj committed Feb 7, 2025
1 parent 73854c6 commit 2e31ff6
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 65 deletions.
4 changes: 3 additions & 1 deletion app/(app)/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { ThreadList } from "@/components/ThreadList";
import { ThreadListHeader } from "@/components/ThreadListHeader";
import { useAvatars } from "@/hooks/useAvatars";
import { useThreads } from "@/hooks/useThreads";
import { clearProfilePushToken } from "@/utils/notifications";

export default function Index() {
const { medplum, profile } = useMedplumContext();
Expand All @@ -21,7 +22,8 @@ export default function Index() {
const { getAvatarURL, isLoading: isAvatarsLoading } = useAvatars(avatarReferences);
const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);

const handleLogout = useCallback(() => {
const handleLogout = useCallback(async () => {
await clearProfilePushToken(medplum);
medplum.signOut();
router.replace("/sign-in");
}, [medplum, router]);
Expand Down
2 changes: 2 additions & 0 deletions app/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import * as SplashScreen from "expo-splash-screen";
import { StatusBar } from "expo-status-bar";
import { useColorScheme } from "nativewind";
import { useEffect } from "react";
import { Alert } from "react-native";
import { GestureHandlerRootView } from "react-native-gesture-handler";
import {
initialWindowMetrics,
Expand All @@ -36,6 +37,7 @@ const medplum = new MedplumClient({
clientId: oauth2ClientId,
storage: new ExpoClientStorage(),
onUnauthenticated: () => {
Alert.alert("Your session has expired", "Please sign in again.");
router.replace("/sign-in");
},
});
Expand Down
66 changes: 2 additions & 64 deletions contexts/NotificationsContext.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { MedplumClient } from "@medplum/core";
import { useMedplum } from "@medplum/react-hooks";
import Constants from "expo-constants";
import * as Device from "expo-device";
import * as Notifications from "expo-notifications";
import { router } from "expo-router";
import { createContext, useCallback, useContext, useEffect, useRef, useState } from "react";
import { Platform } from "react-native";

import { getPushToken, updateProfilePushToken } from "@/utils/notifications";

Notifications.setNotificationHandler({
handleNotification: async () => ({
shouldShowAlert: true,
Expand All @@ -25,67 +24,6 @@ const NotificationsContext = createContext<NotificationsContextType>({
setUpPushNotifications: async () => false,
});

async function getPushToken() {
let token;

if (!Device.isDevice || Platform.OS === "web") {
return;
}

if (Platform.OS === "android") {
await Notifications.setNotificationChannelAsync("default", {
name: "default",
importance: Notifications.AndroidImportance.MAX,
vibrationPattern: [0, 250, 250, 250],
lightColor: "#FF231F7C",
});
}

try {
const projectId = Constants.expoConfig?.extra?.eas?.projectId;
if (!projectId) {
throw new Error("Missing EAS project ID");
}

token = await Notifications.getExpoPushTokenAsync({
projectId,
});
return token?.data;
} catch (error) {
console.error("Error getting push token:", error);
}
}

async function updateProfilePushToken(medplum: MedplumClient, token: string) {
try {
const profile = medplum.getProfile();
if (!profile) return;

// Check if token already exists and matches
const existingToken = profile.extension?.find(
(e) => e.url === "https://medplum.com/push-token",
)?.valueString;

if (existingToken === token) {
return; // Token hasn't changed, no need to update
}

// Update the token
const extensions =
profile.extension?.filter((e) => e.url !== "https://medplum.com/push-token") || [];
extensions.push({
url: "https://medplum.com/push-token",
valueString: token,
});
await medplum.updateResource({
...profile,
extension: extensions,
});
} catch (error) {
console.error("Error updating push token in Medplum:", error);
}
}

function handleMessageNotificationInteraction(response: Notifications.NotificationResponse) {
const data = response.notification.request.content.data;
if (data.threadId) {
Expand Down
85 changes: 85 additions & 0 deletions utils/notifications.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { MedplumClient } from "@medplum/core";
import Constants from "expo-constants";
import * as Device from "expo-device";
import * as Notifications from "expo-notifications";
import { Platform } from "react-native";

export async function getPushToken() {
let token;

if (!Device.isDevice || Platform.OS === "web") {
return;
}

if (Platform.OS === "android") {
await Notifications.setNotificationChannelAsync("default", {
name: "default",
importance: Notifications.AndroidImportance.MAX,
vibrationPattern: [0, 250, 250, 250],
lightColor: "#FF231F7C",
});
}

try {
const projectId = Constants.expoConfig?.extra?.eas?.projectId;
if (!projectId) {
throw new Error("Missing EAS project ID");
}

token = await Notifications.getExpoPushTokenAsync({
projectId,
});
return token?.data;
} catch (error) {
console.error("Error getting push token:", error);
}
}

export async function updateProfilePushToken(medplum: MedplumClient, token: string) {
try {
const profile = medplum.getProfile();
if (!profile) return;

// Check if token already exists and matches
const existingToken = profile.extension?.find(
(e) => e.url === "https://medplum.com/push-token",
)?.valueString;

if (existingToken === token) {
return; // Token hasn't changed, no need to update
}

// Update the token
const extensions =
profile.extension?.filter((e) => e.url !== "https://medplum.com/push-token") || [];
extensions.push({
url: "https://medplum.com/push-token",
valueString: token,
});
await medplum.updateResource({
...profile,
extension: extensions,
});
} catch (error) {
console.error("Error updating push token in Medplum:", error);
}
}

export async function clearProfilePushToken(medplum: MedplumClient) {
try {
const profile = medplum.getProfile();
if (!profile) return;

// Filter out the push token extension
const extensions =
profile.extension?.filter((e) => e.url !== "https://medplum.com/push-token") || [];

// Update the profile with the filtered extensions
await medplum.updateResource({
...profile,
extension: extensions,
});
} catch (error) {
console.error("Error clearing push token from Medplum:", error);
}
}

0 comments on commit 2e31ff6

Please sign in to comment.