Created
December 4, 2024 03:37
-
-
Save nghiatv/e226dd906cb627be3759ae8c6b8ecacf to your computer and use it in GitHub Desktop.
usePushNotification.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* 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