Reputation: 134
I have an expo app which is installed on both Android and iOS devices. These apps use Firebase as a backend. I have also created a dashboard in Reactjs which is also using same Firebase as a backend.
I want to send notification to a specific user whenever i perform some event on Reactjs Dashboard. e.g: I change the order_status from "pending" to "delivered" then a firebase event changes the order_status for that user in firebase collection so i want the user to know his order has been dispatched.
How can i achieve this for both Android and iOS ?
How can i achieve this for both Android and iOS ?
SOLUTION:
App side code to setup receiving notifications:
const [expoPushToken, setExpoPushToken] = useState('');
const [notification, setNotification] = useState(false);
const notificationListener = useRef();
const responseListener = useRef();
async function sendPushNotification(expoPushToken) {
const message = {
to: expoPushToken,
sound: 'default',
title: 'Original Title',
body: 'And here is the body!',
data: { someData: 'goes here' },
};
console.log(expoPushToken);
await fetch('https://exp.host/--/api/v2/push/send', {
method: 'POST',
headers: {
Accept: 'application/json',
'Accept-encoding': 'gzip, deflate',
'Content-Type': 'application/json',
},
body: JSON.stringify(message),
});
}
async function registerForPushNotificationsAsync() {
let token;
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') {
alert('Failed to get push token for push notification!');
return;
}
token = (await Notifications.getExpoPushTokenAsync()).data;
console.log(token);
} else {
alert('Must use physical device for Push Notifications');
}
if (Platform.OS === 'android') {
Notifications.setNotificationChannelAsync('default', {
name: 'default',
importance: Notifications.AndroidImportance.MAX,
vibrationPattern: [0, 250, 250, 250],
lightColor: '#FF231F7C',
});
}
return token;
}
useEffect(() => {
registerForPushNotificationsAsync().then(token => setExpoPushToken(token));
// This listener is fired whenever a notification is received while the app is foregrounded
notificationListener.current = Notifications.addNotificationReceivedListener(notification => {
setNotification(notification);
});
// This listener is fired whenever a user taps on or interacts with a notification (works when app is foregrounded, backgrounded, or killed)
responseListener.current = Notifications.addNotificationResponseReceivedListener(response => {
console.log(response);
});
return () => {
Notifications.removeNotificationSubscription(notificationListener.current);
Notifications.removeNotificationSubscription(responseListener.current);
};
}, []);
// write below code outside export App function
Notifications.setNotificationHandler({
handleNotification: async () => ({
shouldShowAlert: true,
shouldPlaySound: false,
shouldSetBadge: false,
}),
});
npx expo install expo-notifications
From Above code you can get push Token which at first you can manually use to test notifications, then eventually you can store all user's device push tokens in some firebase DB or custom DB against their uid. Then later use these tokens to send them individual notifications.
Server Side Code:
install this library first npm i node-fetch
push Token looks like this : ExponentPushToken[KA2CcEFolWMq_9TmIddctr]
import fetch from "node-fetch";
async function sendPushNotification(expoPushToken) {
const android = "pushToken";
const ios = "pushToken";
const message = {
to: ios,
sound: 'default',
title: 'Original Title',
body: 'And here is the body!',
data: { someData: 'goes here' },
};
await fetch('https://exp.host/--/api/v2/push/send', {
method: 'POST',
headers: {
Accept: 'application/json',
'Accept-encoding': 'gzip, deflate',
'Content-Type': 'application/json',
},
body: JSON.stringify(message),
});
}
call this function in the end sendPushNotification();
Upvotes: 1
Views: 1167
Reputation: 1731
Here is the code for expo nodejs sdk, check for other languages/frameworks
This is more like pseudo code
import Expo from 'expo-server-sdk';
// let sentNotificationId = //id for entry in db
// generating custom objects to store them in DB
const pushNotificationsItems = [{
// info like userId
// sentNotificationId, entry id etc
// data mostly needed by the app
to: notification.token,
notificationBody: {
// expo push notification related info
to: notification.token, // expo token
title: `Some title`,
body: message,
data: {
//custom data to be used in app
}
}
}
]
// make db entries with data you need
// checking valid expo messages
let tickets = [];
let notificationMessages = [];
for (const notification of pushNotificationsItems) {
if (!Expo.isExpoPushToken(notification.to)) {
continue
}
notificationMessages.push(notification.notificationBody)
}
// send actual notification using expo client
const expo = new Expo({});
const chunks = expo.chunkPushNotifications(notificationMessages);
//console.log('message chunks', chunks)
const resolvedPromises = await Promise.allSettled(map(chunks, async chunk => {
const ticketChunks = await expo.sendPushNotificationsAsync(chunk);
tickets.push(...ticketChunks)
}));
// saving the response if needed
if (tickets.length) {
const mappedTickets = map(tickets, t => {
return {
data: t,
notificationSentId: sentNotificationId,
organisationId,
createdAt: getCurrentUTCISOString() || '',
}
})
await this.prisma.notificationResponse.createMany({
data: [...mappedTickets]
})
}
Hope it helps you in some way
Upvotes: 0