added push notifications

This commit is contained in:
2026-06-03 19:13:56 +02:00
parent a9278b8269
commit 6559a9cd4b
24 changed files with 1598 additions and 557 deletions
+17 -2
View File
@@ -1,7 +1,7 @@
const BASE_URL = process.env.EXPO_PUBLIC_API_URL; // TODO change this
export type NotificationType = 'PUSH_NOTIFICATION' | 'NO_NOTIFICATION';
function authHeader(token?: string) {
return token ? { Authorization: `Bearer ${token}` } : {};
}
@@ -25,7 +25,13 @@ async function request<T>(
headers: { "Content-Type": "application/json", ...authHeader(token) },
...(body ? { body: JSON.stringify(body) } : {}),
});
if (!res.ok) throw new Error(await res.text().catch(() => `HTTP ${res.status}`));
if (!res.ok) {
const errorText = await res.text().catch(() => `HTTP ${res.status}`);
console.log('Failed URL:', res.url);
console.log('Status:', res.status);
console.log('Response:', errorText);
throw new Error(errorText);
}
return res.json();
}
@@ -65,6 +71,7 @@ export type UserDTO = {
id: string;
email: string;
subjectSet: Subject[];
notificationType: NotificationType;
};
@@ -115,6 +122,12 @@ export const authApi = {
};
export const userApi = {
updateNotificationType: (
type: 'PUSH_NOTIFICATION' | 'NO_NOTIFICATION',
token: string
) => post<void>('/users/me/notification-type', { notificationType: type }, token),
};
export const subjectsApi = {
getAll: (token?: string) => get<Subject[]>("/subjects", token),
@@ -135,6 +148,8 @@ export const subscriptionsApi = {
),
};
export const entriesApi = {
getEntries: (params: { subjectId?: string; groupName?: string; page?: number }) =>
get<SpringPage<Entry>>("/entries", undefined, params),
+35
View File
@@ -0,0 +1,35 @@
import {
getMessaging,
requestPermission,
getToken,
onTokenRefresh,
AuthorizationStatus,
} from '@react-native-firebase/messaging';
import { post } from '@/services/api';
export async function registerDeviceToken(authToken: string): Promise<void> {
const messaging = getMessaging();
const status = await requestPermission(messaging);
const granted =
status === AuthorizationStatus.AUTHORIZED ||
status === AuthorizationStatus.PROVISIONAL;
if (!granted) return;
const fcmToken = await getToken(messaging);
await fetch(`${process.env.EXPO_PUBLIC_API_URL}/device-tokens/register`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${authToken}`,
},
body: JSON.stringify({ token: fcmToken }),
});
}
export function listenForTokenRefresh(authToken: string): () => void {
return onTokenRefresh(getMessaging(), async (newToken) => {
await post('/device-tokens/register', { token: newToken }, authToken);
});
}