Way to go direct to defined screen in ReactNative and OneSignal - react-native

I have integrated with OneSignal in my app for push notification, right now I need to handle when user click on the notification.
When user click on the notification, App have to go to screen that have defined in OneSignal but instead of immediately go to defined screen, it land on main screen until receiving event from OneSignal (onOpened event) complete.
constructor(props) {
super(props);
OneSignal.addEventListener('received', this.onReceived);
OneSignal.addEventListener('opened', this.onOpened);
OneSignal.addEventListener('ids', this.onIds);
}
onOpened(openResult) {
const data = openResult.notification.payload.additionalData;
if(data.screen) {
navigationService.navigate(data.screen);
}
}
Do we have any way to let it go direct to defined screen? Thanks

You can use componentWillmount
componentWillmount(openResult) {
this.onOpened(openResult);
}

Related

React native push Notification ontap Navigation

Hello i am Working Push Notification with the help of this https://github.com/zo0r/react-native-push-notification my notification is working fine but i want to navigate the the screen when i tap on notification ! my notifiaction working fine please help me out with any suggestion i used stack navigator in my routes
onNotification: function (notification) {
console.log("NOTIFICATIONss:", notification);
if (notification.userInteraction) {
console.log("Clicked on Notification"). // here i clicked on notification
this.props.navigation.push("Home"). // here i want navigation
}
if (!notification.userInteraction) {
PushNotification.localNotification({
foreground:false,
channelId: notification.channelId,
channelName: "xShare", //
title: notification.title,
message: notification.message,
largeIconUrl: notification.smallIcon,
onOpen: () => { this.props.navigation.navigate("ActiveNeed") },//nothing working
})
notification.finish(PushNotificationIOS.FetchResult.NoData);
}
},`
If your app is opened through clicking on the notification bubble, the navigation props should be unavailable when the onNotification() function runs.
Therefore, please create a navigation reference for the app. You may follow the guidelines by React-Navigation for more details.
https://reactnavigation.org/docs/navigating-without-navigation-prop
You can use the following code for navigation in onNotification() after you added the navigation-reference.
import * as RootNavigation from './path/to/RootNavigation.js';
RootNavigation.navigate('TargetPage', { someParams: 'someValue' });

How to jump to notification screen when click on notification

I setup notification system with firebase and react native. It's working fine, but when i receive notification in any state of app(killed, fore or background) and do click notification push me to home screen. I want to go on notification screen when someone click on notification.
How it will possible?
First, you have to add a Firebase Notification listener at the top-level component. I'll suggest placing it in App.js.
Foreground Listener
Background Listener
After that, You have to navigate to a particular screen with the help of a navigation prop. if you place the listener at App.js then you will not have access to the navigation prop since App.js will return the navigation container.
For that, you have to create one helper function like this navigation without prop
e.g.
export const App = () => {
messaging().setBackgroundMessageHandler(async remoteMessage => {
navigate('Notification'); //navigate to notification screen
});
const unsubscribe = messaging().onMessage(async remoteMessage => {
//generate local notification using your preferred library
//handle navigation
})
return <RootNavigator />;
};

React Native - Global BackHandler behavior depends on registration timing

I'm migrating an old React Native app from 0.57 to 0.62, and just setup navigation with the current React Navigation package. That app contains a global navigation store that registers to Android back button presses and allows me to intercept back operations, no matter where they originate (hardware button or programmatically).
I have a rather weird behavior here, and it seems to be timing-related. In the snippet below, I register a listener with BackHandler, which supresses back button taps and logs a warning. I'll register it in the componentDidMount method.
export class RootComponent extends React.Component {
private initBackButton() {
const onBackPress = () => {
console.warn("BACK BUTTON SUPPRESSED");
return true;
};
BackHandler.addEventListener("hardwareBackPress", onBackPress);
}
public componentDidMount() {
// TODO register back listener
}
public render() {
return (
<NavigationContainer >
<StackNavigatorSetup />
</NavigationContainer>
);
}
}
If I register the listener synchronously, the back button listener fires if I press it at the initial screen of my StackNavigator.
If I navigate to a second screen, the listener does not fire if I press the back button, and I can return back to the start screen. If I press back there again, the listener fires.
Note that I'm declaring the listener in the root component, so that component isn't going anywhere.
public componentDidMount() {
// only works on the start screen
this.initBackButton();
}
Now, the behavior is different if I use a delay:
If I register the same handler with a delay of 1 second, the handler works on any screen
This is not thread-related. If I use a delay that is too short, it again only works on the start screen
public componentDidMount() {
// works on every screen i'll navigate to
PromiseUtil.delay(1000).then(() => this.initBackButton());
}
To be honest, I don't really have a clue what's happening here. BackHandler seems to be ready, but I don't understand why the listener works either global or not depending on the delay. Also, my root component doesn't really change, so I wonder whether React Navigation is messing with me here...

How to use Blur event for AppState in react native

Please I need an example on how to use the 'blur' event for react native AppState. I am trying to respond to when the app is not in focus e.g. when the user pulls the notification drawer but I keep getting the error message Invariant Violation: Trying to subscribe to unknown event: "blur".
Based on the tags associated with the commit that this feature landed in (https://github.com/facebook/react-native/commit/d45818fe47c53a670db933cf805910e227aa79c9) it seems like that is only available starting in 0.61 and hasn't landed in a stable release yet. Make sure you're running 0.61.0-rc.0 or later.
According to documentation . Blur is [Android only]
"[Android only] Received when the user is not actively interacting with the app. Useful in situations when the user pulls down the notification drawer. AppState won't change but the blur event will get fired."
if you still want to use it for android you can use it with condition for android only
import { Platform } from "react-native";
........
componentDidMount() {
if (Platform.OS === "android") {
AppState.addEventListener("blur", this._handleAppStateBlur);
}
}
componentWillUnmount() {
if (Platform.OS === "android") {
AppState.removeEventListener("blur", this._handleAppStateBlur);
}
}
_handleAppStateBlur = () => {
console.log("blur");
};
According to the docs mentioned in the official react native documentation, there are three states supported by AppState:
active - The app is running in the foreground.
background - The app is running in the background. The user is either:
in another app
on the home screen
[Android] on another Activity (even if it was launched by your app)
[iOS] inactive - This is a state that occurs when transitioning between foreground & background, and during periods of inactivity such as entering the Multitasking view or in the event of an incoming call.
Since there is no such state as blur, therefore you are facing an error saying that it could not find such event.
Edit
You have to register blur as an event in your component lifecycle, but you have to be cautious here and have to determine the Platform before registering blur event as it is available in android only and not in ios.
To register an event you have to do this:
import React from 'react';
import {AppState} from 'react-native';
class HandlingEvents extends React.Pure.Component {
constructor(props) {
super(props)
// your state goes here...
}
componentDidMount() {
// your event will be registered here, when your component is mounted on // the screen.
// Be cautious here, make a platform check here so as to avoid discrepancies in ios devices
AppState.addEventListener('blur',this.handleBlurState)
}
componentWillUnMount() {
// your event will be removed here, when your component gets unmounted from the screen.
// Be cautious here, make a platform check here so as to avoid discrepancies in ios devices
AppState.removeEventListener('blur',this.handleBlurState)
}
handleBlurState = (nextAppState) => {
//this method will contain your entire logic, as to how you want to treat your component in this event.
// As per the docs, since the state of your app will not changed, therefore you can continue your logic here by checking if the state of your app is **change** or not..
if (AppState.currentState === "active" && nextAppState === "active") {
//whatever task you want to perform here..;
}
}
}

react native push notification that can be removed after button click

I am using react native v0.45.1.
How can I add to my application notification (no matter if the app is in the background or foreground) that the user can remove only after click an acknowledge button.
I don't want the user to swipe the notification aside without notice it.
how can it be done?
I am not sure https://github.com/wix/react-native-notifications will do what I need.
Edit
I want to have a notification that will act like:
'USB debugging connected
'Touch to disable USB debugging'
The notification can't be removed unless the user actively do something, in my case it will be 'click' on a button
after a lot of digging the solution I implemented was:
setting repeat interval for the notification.
for android:
repeatType: 'time',
repeatTime: timeSpan,
for iOS:
repeatType: 'minute',
when the user click the notification (decided its not the right approached to add actions - buttons - to notification):
PushNotification.configure({
onNotification: (notification) => {
console.log('NOTIFICATION:', notification);
const clicked = notification.userInteraction;
if (clicked) {
if (Platform.OS === 'ios') {
PushNotification.cancelLocalNotifications({ id: notification.data.id });
} else {
PushNotification.cancelLocalNotifications({ id: notification.id });
}
}
},
});
I am aware that this might not be the exact answer to this question. However,
I was looking for a similar solution earlier; how to remove notifications that hasn't been dismissed or opened by a user.
Sometimes the user might open the application / screen, without clicking on the notification. The notification will still be displayed in that case.
Using React Native with Expo, this is the solution I created for removing old notifications created using their Push Notification API.
import * as Notifications from "expo-notifications";
//...
// Remove notifications that exists for this conversation!
useEffect(() => {
Notifications.getPresentedNotificationsAsync().then(res => {
for (let k in res) {
if (
res[k].request.content.data &&
res[k].request.content.data.screen === "Conversations" &&
res[k].request.content.data.conversationId === conversationId
) {
Notifications.dismissNotificationAsync(res[k].request.identifier);
console.log("removed a notification for this conversation");
}
}
});
}, []);
By using the data sent to the Push Notification API, we can determine which notifications should be removed. in this case all notifications containing a conversationId matching the current value from the route are dismissed.