Skip to content

Instantly share code, notes, and snippets.

@nghiatv
Created December 4, 2024 03:37
Show Gist options
  • Save nghiatv/e226dd906cb627be3759ae8c6b8ecacf to your computer and use it in GitHub Desktop.
Save nghiatv/e226dd906cb627be3759ae8c6b8ecacf to your computer and use it in GitHub Desktop.
usePushNotification.ts
/* eslint-disable react-hooks/exhaustive-deps */
import {REGISTER_NOTIFICATION_TOKEN} from '@/apollo/mutations/notification';
import {isApolloError, useMutation} from '@apollo/client';
import {useCallback} from 'react';
import {
registerNotificationToken,
registerNotificationTokenVariables,
} from '__generated__/registerNotificationToken';
import {useMMKV, useMount} from './index';
import CleverTap from 'clevertap-react-native';
import Config from 'react-native-config';
import messaging from '@react-native-firebase/messaging';
import {
getTokenFirebase,
hasPermission,
requestPermission,
} from '@/helpers/fcm';
import {useToast} from '@/libs/Toast/ToastProvider';
import {graphqlErrorParser} from '@/helpers/apollo';
import {InteractionManager, PermissionsAndroid, Platform} from 'react-native';
import {UPDATE_NOTIFICATION_TOKEN} from '@/apollo/mutations/deviceManagement';
import {
updateNotificationToken,
updateNotificationTokenVariables,
} from '__generated__/updateNotificationToken';
import {useDeviceInfo} from './useDeviceInfo';
import DeviceInfo from 'react-native-device-info';
const usePushNotification = () => {
const {
value: {uniqueId},
} = useDeviceInfo();
const [fcmToken, setFcmToken] = useMMKV('fcmTokenV2');
const {show} = useToast();
const [registerNotification] = useMutation<
registerNotificationToken,
registerNotificationTokenVariables
>(REGISTER_NOTIFICATION_TOKEN, {
errorPolicy: 'ignore',
});
const [updateNotificationTokenMutation] = useMutation<
updateNotificationToken,
updateNotificationTokenVariables
>(UPDATE_NOTIFICATION_TOKEN, {
errorPolicy: 'ignore',
});
const requestUserPermission = useCallback(async () => {
try {
let authStatus = null;
if (!fcmToken) {
if (Platform.OS === 'android' && DeviceInfo.getApiLevelSync() >= 33) {
const res = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS,
);
if (res !== PermissionsAndroid.RESULTS.GRANTED) {
throw new Error('Permission not granted');
}
}
authStatus = await requestPermission();
} else {
authStatus = await hasPermission();
}
const enabled =
authStatus === messaging.AuthorizationStatus.AUTHORIZED ||
authStatus === messaging.AuthorizationStatus.PROVISIONAL;
if (enabled) {
CleverTap.registerForPush();
CleverTap.createNotificationChannel(
Config.CLEAVERTAP_CHANNEL || 'sandbox',
Config.CLEAVERTAP_CHANNEL || 'sandbox',
Config.CLEAVERTAP_CHANNEL || 'sandbox',
3,
true,
);
const token = await getTokenFirebase();
if (token && fcmToken !== token) {
await registerNotification({
variables: {
payload: {
token,
},
},
optimisticResponse: {
registerNotificationToken: null,
},
});
// we need to update notification token for device
if (uniqueId) {
await updateNotificationTokenMutation({
variables: {
payload: {
notificationToken: token,
deviceId: uniqueId,
},
},
optimisticResponse: {
updateNotificationToken: null,
},
});
}
setFcmToken(token);
}
}
} catch (error) {
if (isApolloError(error)) {
show(graphqlErrorParser(error), 'top', {
type: 'error',
});
}
}
}, [fcmToken, uniqueId, registerNotification, setFcmToken]);
useMount(async () => {
const handle = InteractionManager.createInteractionHandle();
await requestUserPermission();
InteractionManager.clearInteractionHandle(handle);
return () => InteractionManager.clearInteractionHandle(handle);
});
};
export default usePushNotification;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment