150 lines
5.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import Constants from 'expo-constants';
import * as Device from 'expo-device';
import * as Notifications from 'expo-notifications';
import { useEffect, useState } from 'react';
import { Button, Platform, Text, View } from 'react-native';
import { requestNotificationPermission } from '../owner/utils';
Notifications.setNotificationHandler({
handleNotification: async () => ({
shouldPlaySound: false,
shouldSetBadge: false,
shouldShowBanner: true,
shouldShowList: true,
}),
});
export default function AuthNotifications({ setNotificationsEnabled, notificationsEnabled }: { setNotificationsEnabled: (value: boolean) => void, notificationsEnabled: boolean }) {
const [expoPushToken, setExpoPushToken] = useState('');
const [channels, setChannels] = useState<Notifications.NotificationChannel[]>([]);
const [notification, setNotification] = useState<Notifications.Notification | undefined>(
undefined
);
useEffect(() => {
console.log('notificationsEnabled', notificationsEnabled);
registerForPushNotificationsAsync().then(token => {
console.log('token', token);
token && setExpoPushToken(token)
});
if (Platform.OS === 'android') {
Notifications.getNotificationChannelsAsync().then(value => setChannels(value ?? []));
}
const notificationListener = Notifications.addNotificationReceivedListener(notification => {
setNotification(notification);
});
const responseListener = Notifications.addNotificationResponseReceivedListener(response => {
console.log(response);
});
return () => {
notificationListener.remove();
responseListener.remove();
};
}, [notificationsEnabled]);
return (
<View
style={{
flex: 1,
alignItems: 'center',
justifyContent: 'space-around',
display: "none"
}}>
<Text>Your expo push token: {expoPushToken}</Text>
<Text>{`Channels: ${JSON.stringify(
channels.map(c => c.id),
null,
2
)}`}</Text>
<View style={{ alignItems: 'center', justifyContent: 'center' }}>
<Text>Title: {notification && notification.request.content.title} </Text>
<Text>Body: {notification && notification.request.content.body}</Text>
<Text>Data: {notification && JSON.stringify(notification.request.content.data)}</Text>
</View>
<Button
title="Press to schedule a notification"
onPress={async () => {
await schedulePushNotification();
}}
/>
</View>
);
}
async function schedulePushNotification() {
await Notifications.scheduleNotificationAsync({
content: {
title: "You've got mail! 📬",
body: 'Here is the notification body',
data: { data: 'goes here', test: { test1: 'more data' } },
},
trigger: {
type: Notifications.SchedulableTriggerInputTypes.TIME_INTERVAL,
seconds: 2,
},
});
}
async function registerForPushNotificationsAsync() {
let token;
// 1. Android 特定配置
if (Platform.OS === 'android') {
await Notifications.setNotificationChannelAsync('myNotificationChannel', {
name: 'A channel is needed for the permissions prompt to appear',
importance: Notifications.AndroidImportance.MAX, // 最高优先级
vibrationPattern: [0, 250, 250, 250], // 振动模式
lightColor: '#FF231F7C', // 通知灯颜色
});
}
// 2. 检查是否在真实设备上运行
if (Device.isDevice) {
// 3. 检查通知权限状态
const { status: existingStatus } = await Notifications.getPermissionsAsync();
let finalStatus = existingStatus;
// 4. 如果尚未授予权限,则请求权限
if (existingStatus !== 'granted') {
const granted = await requestNotificationPermission();
finalStatus = granted ? Notifications.PermissionStatus.GRANTED : Notifications.PermissionStatus.DENIED;
}
// 5. 如果权限被拒绝,显示警告并返回
if (finalStatus !== 'granted') {
console.log('用户拒绝了通知权限');
return;
}
// 6. 获取推送令牌
try {
// 获取项目ID用于Expo推送通知服务
const projectId =
Constants?.expoConfig?.extra?.eas?.projectId ??
Constants?.easConfig?.projectId;
if (!projectId) {
throw new Error('Project ID not found');
}
// 获取Expo推送令牌
token = (
await Notifications.getExpoPushTokenAsync({
projectId,
})
).data;
console.log(token); // 打印令牌,实际应用中应该发送到你的服务器
} catch (e) {
token = `${e}`; // 错误处理
}
} else {
// 7. 如果是在模拟器上运行,显示警告
alert('Must use physical device for Push Notifications');
}
return token; // 返回获取到的令牌
}