React native - How to navigate on Push notification click?

Viewed 4536

I am using react-native-push-notification. I had the issue of notifications not being displayed when the app is in background/killed state, to which the solution in multiple forums and GitHub is that we initialize and configure push notification (PushNotification.configure()) in index.js Inside the PushNotification.configure() function, onNotification() is the function called when the Push Notification is clicked. On click, I want to navigate to a particular screen in the app, but that is not possible currently as there is no navigation prop available in index.js

Is there any way the navigation could be made possible ?

2 Answers

This is what you can do. Firstly, you can initialize and export navigationRef from the file in which you've NavigationContainer.

// App.js
    
import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { navigationRef } from './RootNavigation';

export const navigationRef = React.createRef();

export function navigate(name, params) {
  navigationRef.current?.navigate(name, params);
}
    
export default function App() {
  return (
        <NavigationContainer ref={navigationRef}>{/* ... */}</NavigationContainer>
  );
}

then you can import it in which you've PushNotification.configure()

// notification-service.js

import PushNotification from 'react-native-push-notification';
import { navigationRef } from './App';

/* Your other code */

PushNotification.configure({
  onNotifications: (notification) => {
  
  // Now you'll have access to the navigation object's function here...

  }
})

You can get more clarity from the docs here: navigating-without-navigation-prop

Try with React Native Firebase

Example:

import React, { useState, useEffect } from 'react';
import messaging from '@react-native-firebase/messaging';
import { NavigationContainer, useNavigation } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';

const Stack = createStackNavigator();

function App() {
  const navigation = useNavigation();
  const [loading, setLoading] = useState(true);
  const [initialRoute, setInitialRoute] = useState('Home');

  useEffect(() => {
    // Assume a message-notification contains a "type" property in the data payload of the screen to open

    messaging().onNotificationOpenedApp(remoteMessage => {
      console.log(
        'Notification caused app to open from background state:',
        remoteMessage.notification,
      );
      navigation.navigate(remoteMessage.data.type);
    });

    // Check whether an initial notification is available
    messaging()
      .getInitialNotification()
      .then(remoteMessage => {
        if (remoteMessage) {
          console.log(
            'Notification caused app to open from quit state:',
            remoteMessage.notification,
          );
          setInitialRoute(remoteMessage.data.type); // e.g. "Settings"
        }
        setLoading(false);
      });
  }, []);

  if (loading) {
    return null;
  }

  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName={initialRoute}>
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen name="Settings" component={SettingsScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
Related