react-navigation.github.io icon indicating copy to clipboard operation
react-navigation.github.io copied to clipboard

Document the best possible way of navigation upon receiving push notification background and foreground

Open shekharskamble opened this issue 7 years ago • 9 comments

This is a general question to all who are using react navigation, there is no documentation as to navigate to particular screen when user receives a notification

export const createRootNavigator = (signedIn = false) => {
  return StackNavigator({
      Login: screen: Login,
      Welcome: screen: Welcome,
      Loading: screen: Loading,
      SignedIn: screen:  SignedIn,
    });
};

export const SignedIn = TabNavigator ({
    Home: screen: HomeNavigation, 
    FeedBack: screen: FeedBackNavigation, 
    Search: screen: SearchNavigation, 
    Me: screen: ProfileNavigation,  
});

I am using 'react-native-fcm' to receive the notification when app is in foreground or closed. How should I structure the code to navigate to specific screens upon receiving notification? Shall I subscribe to onNotification in every screen and then navigate to specific screen or have it at a centralized place? Has anyone tackled this before? sample code would be great

software version
react-navigation 1.0.0-beta.26
react-native 0.49.3

shekharskamble avatar Mar 06 '18 02:03 shekharskamble

seems like a decent use case to have documentation for

brentvatne avatar Mar 23 '18 19:03 brentvatne

@shekharskamble I've been like 2 months looking for this :/

Did you find any solution?

frangeris avatar Apr 28 '18 20:04 frangeris

@frangeris https://reactnavigation.org/docs/navigating-without-navigation-prop.html

brentvatne avatar Apr 30 '18 19:04 brentvatne

@frangeris - combination of deeplink & react-native-fcm (FCM.on event in home screen), pass screen property in the notification and route based on that. Thats how I achieved it still not done 100% tough

shekharskamble avatar May 02 '18 09:05 shekharskamble

any help please .... @frangeris

MahmoudYaser1 avatar May 13 '18 20:05 MahmoudYaser1

Sorry for delay @dekemega

I get this working but using react-native-firebase, if intersted let me know, I'll prepare some snippets...

frangeris avatar May 22 '18 16:05 frangeris

yes i would like to learn more about that .. thank you mr. @frangeris

MahmoudYaser1 avatar May 23 '18 06:05 MahmoudYaser1

Here's

First configure your deep links and install react-native-firebase

Then, in some starting point of you app, start creating the channel for firebase.

// bootstrap.js
import firebase from 'react-native-firebase'

let channel = new firebase.notifications.Android.Channel('main', 'main', firebase.notifications.Android.Importance.Max)
firebase.notifications().android.createChannel(channel)

Later in the route where you control the access (can be the root view), I've a dedicate object for route as root point.

// config/router.js

import firebase from 'react-native-firebase'
const DEEPLINK_ROUTE = 'myapp://myroute/'

// define the path for the view
let Stack = StackNavigator(
    // .....
    MyRoute: {
      path: 'myroute/:id',
      screen: require('@components/views/myroute').default
    },
)

// helper function to local notifications
let notify = function (notif) {
  let local = new firebase.notifications.Notification()
    .setNotificationId('main')
    .setTitle(notif._title)
    .setBody(notif._body)
    .setData(notif._data)
    .setSound('default')

  if (Platform.OS === 'android') {
    local
      .android.setChannelId('main')
      .android.setAutoCancel(true)
      .android.setDefaults(firebase.notifications.Android.Defaults.All)
      .android.setBadgeIconType(firebase.notifications.Android.BadgeIconType.Small)
      .android.setCategory(firebase.notifications.Android.Category.Recommendation)
  }

  firebase.notifications().displayNotification(local)
}

@inject('user', 'notifications')
@observer
export default class Router extends React.Component {
  constructor (props) {
    super(props)

    // foreground push notifications
    firebase.notifications().onNotification(async notif => {
      console.log('onNotification', notif)

      // save the notification on phone
      this.props.notifications.save(notif._data)

      notify(notif)
      // set badge number
      // let badge = await firebase.notifications().getBadge()
      // await firebase.notifications().setBadge(badge + 1)
    })

    // opened notification
    firebase.notifications().onNotificationOpened(opened => {
      console.log('onNotificationOpened', opened)
      this.props.notifications.save(opened.notification._data)

      // go to campaign
      Linking.openURL(`${DEEPLINK_ROUTE}${opened.notification._data.id}`)
    })
  }

  async componentWillMount () {
    // initial, pending notification
    let pending = await firebase.notifications().getInitialNotification()
    if (pending) {
      console.log('getInitialNotification', pending)
      this.props.notifications.save(pending.notification._data)

      // go to campaign
      Linking.openURL(`${DEEPLINK_ROUTE}${pending.notification._data.id}`)
      await firebase.notifications().removeAllDeliveredNotifications()
    }
  }

  render () {
    if (this.props.user.logged === null) {
      return <Loading />
    }

    if (!this.props.user.logged) {
      return <Login />
    }

    return <Stack ref={nav => (this.navigator = nav)} />
  }
}

Hope to help 🍻

frangeris avatar Jun 25 '18 04:06 frangeris

I know this is quite old but it seems even more relevant with v5. I would love to see some documentation on how to handle push notifications while the app is in the background and the user is logged out (using the new auth flow).

eliw00d avatar Jul 20 '20 20:07 eliw00d