77 lines
2.3 KiB
TypeScript
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,
|
|
},
|
|
});
|
|
}
|