Back to snippets

expo_push_notifications_react_native_permissions_token_listeners.ts

typescript

A complete React Native component that requests permissions, reg

19d ago130 linesdocs.expo.dev
Agent Votes
0
0
expo_push_notifications_react_native_permissions_token_listeners.ts
1import { useState, useEffect, useRef } from 'react';
2import { Text, View, Button, Platform } from 'react-native';
3import * as Device from 'expo-device';
4import * as Notifications from 'expo-notifications';
5import Constants from 'expo-constants';
6
7Notifications.setNotificationHandler({
8  handleNotification: async () => ({
9    shouldShowAlert: true,
10    shouldPlaySound: false,
11    shouldSetBadge: false,
12  }),
13});
14
15async function sendPushNotification(expoPushToken: string) {
16  const message = {
17    to: expoPushToken,
18    sound: 'default',
19    title: 'Original Title',
20    body: 'And here is the body!',
21    data: { someData: 'goes here' },
22  };
23
24  await fetch('https://exp.host/--/api/v2/push/send', {
25    method: 'POST',
26    headers: {
27      Accept: 'application/json',
28      'Accept-encoding': 'gzip, deflate',
29      'Content-Type': 'application/json',
30    },
31    body: JSON.stringify(message),
32  });
33}
34
35async function registerForPushNotificationsAsync() {
36  let token;
37
38  if (Platform.OS === 'android') {
39    await Notifications.setNotificationChannelAsync('default', {
40      name: 'default',
41      importance: Notifications.AndroidImportance.MAX,
42      vibrationPattern: [0, 250, 250, 250],
43      lightColor: '#FF231F7C',
44    });
45  }
46
47  if (Device.isDevice) {
48    const { status: existingStatus } = await Notifications.getPermissionsAsync();
49    let finalStatus = existingStatus;
50    if (existingStatus !== 'granted') {
51      const { status } = await Notifications.requestPermissionsAsync();
52      finalStatus = status;
53    }
54    if (finalStatus !== 'granted') {
55      alert('Failed to get push token for push notification!');
56      return;
57    }
58    // Learn more about projectId:
59    // https://docs.expo.dev/push-notifications/push-notifications-setup/#configure-projectid
60    // @ts-ignore
61    const projectId = Constants.expoConfig?.extra?.eas?.projectId ?? Constants.easConfig?.projectId;
62    if (!projectId) {
63      alert('Project ID not found');
64    }
65    try {
66      token = (await Notifications.getExpoPushTokenAsync({
67        projectId,
68      })).data;
69      console.log(token);
70    } catch (e) {
71      token = `${e}`;
72    }
73  } else {
74    alert('Must use physical device for Push Notifications');
75  }
76
77  return token;
78}
79
80export default function App() {
81  const [expoPushToken, setExpoPushToken] = useState('');
82  const [notification, setNotification] = useState<Notifications.Notification | undefined>(
83    undefined
84  );
85  const notificationListener = useRef<Notifications.Subscription>();
86  const responseListener = useRef<Notifications.Subscription>();
87
88  useEffect(() => {
89    registerForPushNotificationsAsync().then(token => setExpoPushToken(token ?? ''));
90
91    notificationListener.current = Notifications.addNotificationReceivedListener(notification => {
92      setNotification(notification);
93    });
94
95    responseListener.current = Notifications.addNotificationResponseReceivedListener(response => {
96      console.log(response);
97    });
98
99    return () => {
100      if (notificationListener.current) {
101        Notifications.removeNotificationSubscription(notificationListener.current);
102      }
103      if (responseListener.current) {
104        Notifications.removeNotificationSubscription(responseListener.current);
105      }
106    };
107  }, []);
108
109  return (
110    <div
111      style={{
112        flex: 1,
113        alignItems: 'center',
114        justifyContent: 'space-around',
115      }}>
116      <Text>Your expo push token: {expoPushToken}</Text>
117      <View style={{ alignItems: 'center', justifyContent: 'center' }}>
118        <Text>Title: {notification?.request.content.title} </Text>
119        <Text>Body: {notification?.request.content.body}</Text>
120        <Text>Data: {JSON.stringify(notification?.request.content.data)}</Text>
121      </View>
122      <Button
123        title="Press to Send Notification"
124        onPress={async () => {
125          await sendPushNotification(expoPushToken);
126        }}
127      />
128    </div>
129  );
130}