Files
FEDEO/mobile/src/lib/push-registration.ts

77 lines
2.3 KiB
TypeScript

import Constants from 'expo-constants';
import * as Notifications from 'expo-notifications';
import * as SecureStore from 'expo-secure-store';
import { Platform } from 'react-native';
import { registerMobilePushDevice } from '@/src/lib/api';
const DEVICE_ID_KEY = 'fedeo.mobilePush.localDeviceId';
Notifications.setNotificationHandler({
handleNotification: async () => ({
shouldPlaySound: true,
shouldSetBadge: true,
shouldShowBanner: true,
shouldShowList: true,
}),
});
function createLocalDeviceId(): string {
const random = typeof crypto !== 'undefined' && 'randomUUID' in crypto
? crypto.randomUUID()
: `${Date.now()}-${Math.random().toString(36).slice(2)}`;
return `mobile-${random}`;
}
async function getLocalDeviceId() {
const existing = await SecureStore.getItemAsync(DEVICE_ID_KEY);
if (existing) return existing;
const created = createLocalDeviceId();
await SecureStore.setItemAsync(DEVICE_ID_KEY, created);
return created;
}
async function ensurePushPermission() {
const current = await Notifications.getPermissionsAsync();
if (hasPushPermission(current)) return;
const requested = await Notifications.requestPermissionsAsync();
if (!hasPushPermission(requested)) {
throw new Error('Push-Mitteilungen wurden nicht erlaubt.');
}
}
function hasPushPermission(status: unknown): boolean {
const permission = status as { granted?: boolean; status?: string };
return permission.granted === true || permission.status === 'granted';
}
export async function registerDeviceForPush(token: string) {
if (Platform.OS !== 'ios' && Platform.OS !== 'android') {
throw new Error('Mobile Push ist nur auf iOS und Android verfügbar.');
}
await ensurePushPermission();
const deviceToken = await Notifications.getDevicePushTokenAsync();
const providerToken = String(deviceToken.data || '');
if (!providerToken) {
throw new Error('Es wurde kein nativer Push-Token zurückgegeben.');
}
return await registerMobilePushDevice(token, {
localDeviceId: await getLocalDeviceId(),
platform: Platform.OS,
providerToken,
deviceLabel: Constants.deviceName || `${Platform.OS} Gerät`,
meta: {
os: Platform.OS,
osVersion: Platform.Version,
expoRuntimeVersion: Constants.expoConfig?.runtimeVersion || null,
appVersion: Constants.expoConfig?.version || null,
},
});
}