UNPKG

@kode-frontend/react-native-push-notification

Version:
282 lines (251 loc) 6.5 kB
import notifee, { AndroidBigPictureStyle, AndroidStyle, AuthorizationStatus, IOSNotificationAttachment, InitialNotification, TriggerNotification, } from '@notifee/react-native' import messaging, { FirebaseMessagingTypes, } from '@react-native-firebase/messaging' import { Image, Linking, Platform } from 'react-native' import { TFirebaseRemoteMessage, TPushNotificationBody } from './types' import { isPermisionsGrantedByDefault } from '../model/constanst' let initialRemotePushWasGetting = false let initialLocalPushWasGetting = false const isPermitted = (authorizationStatus: AuthorizationStatus) => { return ( authorizationStatus === AuthorizationStatus.AUTHORIZED || authorizationStatus === AuthorizationStatus.PROVISIONAL ) } /** * Checks for permissions to send notifications */ export async function hasPermission() { const status = await notifee.getNotificationSettings() return isPermitted(status.authorizationStatus) } /** * Request permissions to receive push notifications */ export async function requestPermission() { const status = await notifee.requestPermission() return isPermitted(status.authorizationStatus) } /** * Checks and request permissions to receive push notifications */ export async function checkPermission() { const enabledNotifications = await hasPermission() if (!enabledNotifications && !isPermisionsGrantedByDefault) { return await requestPermission() } return enabledNotifications } /** * Generating message id */ const createUUIDService = () => { let id = 0 return { getUuid: () => { return String(++id) }, } } const UUIDService = createUUIDService() /** * Receives scheduled local push notifications */ export function getScheduledLocalNotifications(): Promise< TriggerNotification[] > { return new Promise((resolve, reject) => { try { const notifications = notifee.getTriggerNotifications() resolve(notifications) } catch (e) { reject(e) } }) } /** * Cancels all local pushes */ export function cancelAllNotifications(): Promise<void> { return new Promise(async (resolve, reject) => { try { const notifications = await getScheduledLocalNotifications() const notificationIds = notifications.map( item => item.notification.id ?? '', ) resolve(notifee.cancelAllNotifications(notificationIds)) } catch (e) { reject(e) } }) } /** * Cancels local push by id */ export function cancelNotification(notificationId: string): Promise<void> { return new Promise((resolve, reject) => { try { resolve(notifee.cancelNotification(notificationId)) } catch (e) { reject(e) } }) } /** * Gets the initial remote push (from Firebase) */ export function getInitialPush(): Promise<FirebaseMessagingTypes.RemoteMessage | null> { return new Promise((resolve, reject) => { try { if (initialRemotePushWasGetting) { return resolve(null) } const initialPush = messaging().getInitialNotification() resolve(initialPush) initialRemotePushWasGetting = true } catch (e) { reject(e) } }) } /** * Gets the initial local push */ export function getInitialLocalPush(): Promise<InitialNotification | null> { return new Promise((resolve, reject) => { try { if (initialLocalPushWasGetting) { return resolve(null) } const initialPush = notifee.getInitialNotification() resolve(initialPush) initialLocalPushWasGetting = true } catch (e) { reject(e) } }) } /** * Gets the Firebase FCM-token for push notifications */ export const getToken = async () => { try { const enabledNotifications = await checkPermission() if (!enabledNotifications) { return null } } catch (e) { return null } let fcmToken = null try { fcmToken = await messaging().getToken() return fcmToken } catch (e) {} return fcmToken } /** * Removes the FCM-token in Firebase. The device will not be able to receive push notifications */ export const removeToken = async () => { await messaging().deleteToken() } /** * Go to notification settings */ export const openSettings = Platform.select({ ios: Linking.openSettings, android: notifee.openNotificationSettings, })! /** * Set the number on the badge (iOS) */ export const setApplicationIconBadgeNumber = (number: number) => { try { notifee.setBadgeCount(number) } catch (e) {} } /** * Increases the number on the badge (iOS) */ export const incrementApplicationIconBadgeNumber = () => { try { notifee.incrementBadgeCount() } catch (e) {} } /** * Decreases the number on the badge (iOS) */ export const decrementApplicationIconBadgeNumber = () => { try { notifee.decrementBadgeCount() } catch (e) {} } /** * Retrieves attachment on iOS from remoteMessage */ export const getIosAttachment = async (message: TFirebaseRemoteMessage) => { if (message.data?.fcm_options?.image) { try { /** * Let's make sure the attachment is available on iOS */ await Image.prefetch(message.data.fcm_options.image) } catch (e) { delete message.data.fcm_options.image } } const attachment: IOSNotificationAttachment[] = message.data?.fcm_options ?.image ? [ { url: message.data.fcm_options.image, }, ] : [] return attachment } /** * Retrieves attachment on Android from remoteMessage */ export const getAndroidAttachment = async ( message: FirebaseMessagingTypes.RemoteMessage, ) => { if (message.notification?.android?.imageUrl) { try { /** * Let's make sure the attachment is available on Android */ await Image.prefetch(message.notification.android.imageUrl) } catch (e) { delete message.notification.android.imageUrl } } const attachment: AndroidBigPictureStyle | undefined = message.notification ?.android?.imageUrl ? { type: AndroidStyle.BIGPICTURE, picture: message.notification.android.imageUrl, } : undefined return attachment } export const mapRemotePushToLocalPush = ( remotePush: FirebaseMessagingTypes.RemoteMessage, ) => { const pushNotification: TPushNotificationBody = { id: UUIDService.getUuid(), title: remotePush.notification?.title ?? '', body: remotePush.notification?.body ?? '', data: remotePush.data, } return pushNotification }