Last active
March 13, 2023 06:58
-
-
Save dungkaka/3b622e58fc3047a46118823f856bf2ef to your computer and use it in GitHub Desktop.
Expo push notification !
This file contains 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
import { showToast } from "@common-ui/ToastNotify/ToastManager"; | |
import { useNavigation } from "@react-navigation/native"; | |
import { CHATFROM } from "constant/chat"; | |
import { NAVIGATION } from "constant/navigation"; | |
import * as Notifications from "expo-notifications"; | |
import { useEffect } from "react"; | |
import { Platform } from "react-native"; | |
import * as Device from "expo-device"; | |
/* Hàm dùng để lắng nghe dữ liệu nhận được từ push notification khi click vào | |
1 notification trả về sẽ có dữ liệu bao gồm title, body, data. Title và body sẽ hiển thị | |
ngay trên push notification. Để lấy được nhiều hơn thông tin về push notification, server | |
sẽ gửi push notification kèm dữ liệu thông qua trường data. | |
Ví dụ: { | |
to: ExponentToken, | |
title: "Khuyến mãi ngày 8/3", | |
body: "Tưng bừng chương trình khuyến mãi ngày 8/3 với nhiều ưu đãi", | |
data: { | |
type: "NEWS", | |
link: "https: ...." | |
} | |
hoặc dữ liệu cho 1 tin nhắn mới: | |
{ | |
to: ExponentToken, | |
title: "Tin nhắn mới", | |
body: "Máy dao cạo râu: Anh ơi em muốn xin thông tin sản phẩm!", | |
data: { | |
type: "MESSAGE_FACEBOOK", | |
... | |
} | |
}. | |
Trường data thường để điều hướng tới màn hình cần khi bấm vào notification với dữ liệu nào đó. | |
Gọi hook useListenResponseNotification() đặt trong màn hình home (tức là sau khi đã đăng nhập). | |
Lưu ý ở API login, gửi kèm theo luôn push notification tương ứng vs người dùng để server lưu vào | |
(getExpoPushToken) | |
} | |
*/ | |
export const useListenResponseNotification = () => { | |
const navigation = useNavigation(); | |
useEffect(() => { | |
// checkLastNoti: Lấy dữ liệu từ notification bấm vào push notification trong khi app đang tắt | |
// (tắt ở cả background) | |
const checkLastNoti = async () => { | |
const lastNotificationResponse = await Notifications.getLastNotificationResponseAsync(); | |
const data = lastNotificationResponse?.notification?.request?.content?.data || {}; | |
if (lastNotificationResponse?.actionIdentifier === Notifications.DEFAULT_ACTION_IDENTIFIER) { | |
// Dựa vào type trong data để xử lí điều hướng hoặc mục đích khác. | |
// if (data.type?.includes("MESSAGE")) handleDataChatNoti(data, navigation); | |
// else if (data.type?.includes("NOTI")) handleDataInAppNoti(data, navigation); | |
} | |
}; | |
checkLastNoti(); | |
// Lấy dữ liệu từ notification khi bấm vào push notification khi app đang mở hoặc ở background | |
const subscription = Notifications.addNotificationResponseReceivedListener((response) => { | |
const data = response.notification.request.content?.data; | |
// Dựa vào type trong data để xử lí điều hướng hoặc mục đích khác. | |
// if (data.type?.includes("MESSAGE")) handleDataChatNoti(data, navigation); | |
// else if (data.type?.includes("NOTI")) handleDataInAppNoti(data, navigation); | |
}); | |
return () => subscription.remove(); | |
}, []); | |
}; | |
const handleDataChatNoti = (data, navigation) => { | |
const { roomId, type } = data || {}; | |
switch (type) { | |
case "MESSAGE_BAOGIA": | |
return navigation.navigate(NAVIGATION.CHAT_SCREEN, { | |
from: { | |
roomId: roomId, | |
roomName: "Báo giá", | |
name: CHATFROM.BAOGIA, | |
}, | |
}); | |
case "MESSAGE_ORDER": | |
return navigation.navigate(NAVIGATION.CHAT_SCREEN, { | |
from: { | |
roomId: roomId, | |
roomName: "Đơn hàng Order", | |
name: CHATFROM.ORDER, | |
}, | |
}); | |
default: | |
return; | |
} | |
}; | |
const handleDataInAppNoti = (data, navigation) => { | |
const { khuyenmai, type } = data || {}; | |
switch (type) { | |
case "NOTI_TRAODOI": | |
return navigation.navigate(NAVIGATION.LIST_NOTIFICATION, { | |
type: 5, | |
}); | |
case "NOTI_DONHANG": | |
return navigation.navigate(NAVIGATION.LIST_NOTIFICATION, { | |
type: 1, | |
}); | |
default: | |
return; | |
} | |
}; | |
export const getExpoPushToken = async () => { | |
let token = undefined; | |
try { | |
if (Device.isDevice) { | |
const { status: existingStatus } = await Notifications.getPermissionsAsync(); | |
let finalStatus = existingStatus; | |
if (existingStatus !== "granted") { | |
const { status } = await Notifications.requestPermissionsAsync(); | |
finalStatus = status; | |
} | |
if (finalStatus !== "granted") { | |
return; | |
} | |
token = (await Notifications.getExpoPushTokenAsync()).data; | |
return token; | |
} else { | |
showToast({ | |
type: "error", | |
title: "Lỗi", | |
description: "Must use physical device for Push Notifications", | |
}); | |
} | |
} catch (e) { | |
return token; | |
} | |
}; | |
export const listenServerNotification = () => { | |
if (Platform.OS === "android") { | |
Notifications.setNotificationChannelAsync("server", { | |
name: "default", | |
importance: Notifications.AndroidImportance.MAX, | |
vibrationPattern: [0, 250, 250, 250], | |
lightColor: "#FF231F7C", | |
}); | |
} | |
}; | |
export const allowShowNotification = () => { | |
Notifications.setNotificationHandler({ | |
handleNotification: async () => ({ | |
shouldShowAlert: true, | |
shouldPlaySound: true, | |
shouldSetBadge: false, | |
}), | |
}); | |
}; | |
export const preventShowNotification = () => { | |
Notifications.setNotificationHandler({ | |
handleNotification: async () => ({ | |
shouldShowAlert: false, | |
shouldPlaySound: false, | |
shouldSetBadge: false, | |
}), | |
}); | |
}; | |
allowShowNotification(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment