Reputation: 11
Hey guys so I have been trying to implement push notifications to my react-native project for almost 2 weeks now. The idea is if the person is not in the chat room(chat room is present in the app) then the other user's message Is sent via push notification and stored to local storage on the receivers device.
I implemented the push notification service through firebase since literally everyone said its super easy etc. My problem comes when I want to dispatch the notification to my reducer etc using React-Redux when the notification comes in a quit state. I am able to save the message to local storage thanks to redux and persisting storage but when the app is not open im not sure how to achieve this.
Any guides and help would be appreciated!
*PS I even shifted my whole provider, reducer etc to my index.js file so that
messaging().setBackgroundMessageHandler(async remoteMessage => {
console.log('Message handled in the background!', remoteMessage);
dispatch({
type: 'save_message',
data: JSON.parse(remoteMessage.data.message)
})
});
can have access to the provider to save the message but that only works when the app is in background and not when its in a quit state. Also I am using @react-native-firebase/messaging v7.8.3
and @react-native-firebase/app v8.4.1
Upvotes: 1
Views: 3307
Reputation: 1569
USING REDUX IN REACT NATIVE PUSH NOTIFICATION
-->App.js
import { Configure } from './config/NotificationHandler'
const App = () => {
return (
<SafeAreaProvider>
<StatusBar barStyle="dark-content" hidden={false} backgroundColor="#1A1A1A" translucent={true} />
<Provider store={store} >
<Configure />
<View style={{ flex: 1 }} >
<AuthLoading />
</View>
</Provider>
</SafeAreaProvider>
)
}
export default App;
-->Notificationhandler.js
import React, { useEffect } from 'react';
import PushNotificationIOS from "@react-native-community/push-notification-ios";
import PushNotification from 'react-native-push-notification';
import AsyncStorage from '@react-native-community/async-storage';
import NavigationService from '../routing/NavigationService'
import { useDispatch, useSelector, shallowEqual } from 'react-redux';
const Configure = () => {
const { activeProject } = useSelector(state => ({
activeProject: state.homeReducer.activeProject,
}), shallowEqual);
const dispatch = useDispatch();
// Must be outside of any component LifeCycle (such as `componentDidMount`).
PushNotification.configure({
// (optional) Called when Token is generated (iOS and Android)
onRegister: function (token) {
console.log("RNPNonRegistertoken:", token);
AsyncStorage.setItem('fcmToken', token.token);
},
// (required) Called when a remote is received or opened, or local notification is opened
onNotification: function (notification) {
console.log("NOTIFICATION:", notification, activeProject);
// process the notification
if (notification?.data?.url) {
NavigationService.navigate('PDFScreen', { Key: 'URL', urlForPDF: notification.data.url })
} else if (notification.id > 0 && notification.id < 7 && global.notifNavVar) {
global.localPushID = notification.id
NavigationService.navigate('AllTimersButton')
} else if (notification.id == 7 && global.notifNavVarP) {
NavigationService.navigate('ProjectDetail')
}
// (required) Called when a remote is received or opened, or local notification is opened
notification.finish(PushNotificationIOS.FetchResult.NoData);
},
// (optional) Called when Registered Action is pressed and invokeApp is false, if true onNotification will be called (Android)
onAction: function (notification) {
console.log("ACTION:", notification.action);
console.log("NOTIFICATION:", notification);
// process the action
},
// (optional) Called when the user fails to register for remote notifications. Typically occurs when APNS is having issues, or the device is a simulator. (iOS)
// onRegistrationError: function(err) {
// console.error(err.message, err);
// },
// IOS ONLY (optional): default: all - Permissions to register.
permissions: {
alert: true,
badge: true,
sound: true,
},
largeIcon: "ic_launcher",
smallIcon: "ic_launcher",
// Should the initial notification be popped automatically
// default: true
popInitialNotification: true,
/**
* (optional) default: true
* - Specified if permissions (ios) and token (android and ios) will requested or not,
* - if not, you must call PushNotificationsHandler.requestPermissions() later
* - if you are not using remote notification or do not have Firebase installed, use this:
* requestPermissions: Platform.OS === 'ios'
*/
});
return null
};
const LocalNotificationSchedule = (id, afterSec, message = '', title = '') => {
PushNotification.localNotificationSchedule({
//... You can use all the options from localNotifications
id: id + '',
title,
message, // (required)
date: new Date(Date.now() + afterSec * 1000), // in n secs
playSound: true,
// soundName: 'local_notification_custom_tone.mp3',
vibrate: true,
vibration: 180000,
allowWhileIdle: true,
visibility: "public",
// soundName: 'default',
showWhen: true,
usesChronometer: true,
ignoreInForeground: false,
priority: "max",
})
}
const CancelLocalNotifications = (id) => {
PushNotification.cancelLocalNotifications({ id: id + '' })
}
// const LocalNotification = () => {
// PushNotification.localNotification({
// id: 0, // (optional) Valid unique 32 bit integer specified as string. default: Autogenerated Unique ID
// autoCancel: true,
// bigText: 'This is local notification demo in React Native app. Only shown, when expanded.',
// subText: 'Local Notification Demo',
// title: 'Local Notification Title',
// message: 'Expand me to see more',
// vibrate: true,
// vibration: 300,
// playSound: true,
// soundName:'default',
// actions: '["Yes", "No"]'
// })
// }
export {
Configure,
LocalNotificationSchedule,
CancelLocalNotifications,
// LocalNotification
};
Upvotes: 2
Reputation: 1824
In my React Native app I dispatch to the Redux store when the app is killed by using the vanilla Redux API as setBackgroundMessageHandler
is not a React component or hook which don't have access to the Redux provider:
setBackgroundMessageHandler.js:
import store from '../../redux/store';
const setBackgroundMessageHandler = async (remoteMessage) => {
store.dispatch({
type: 'save_message',
data: JSON.parse(remoteMessage.data.message)
})
}
Your data should be safely dispatched from the notification message to the store ready to use once the app loads.
Upvotes: 0