4

Me and a co-worker have been working on a React-Native app for quite some time now. We've been struggling with this problem for a few days now and we don't seem to find a suitable solution.

We are using a few dependencies to make this work.

We've tried using the useNavigation() in the notifee.onBackgroundEvent() but we keep getting an Invalid hook call. When we try to pass the navigation as a property trough the function it returns undefined.

We want to navigate the user to a page after the user has pressed the notification when the app is closed/killed

index.js

import {AppRegistry} from 'react-native';
import React, {useEffect, useState} from 'react';
import messaging from '@react-native-firebase/messaging';
import App from './App';
import {name as appName} from './app.json';
import getNotification from './src/services/RESTnotification';
import notifee, {EventType} from "@notifee/react-native";
import {useNavigation} from "@react-navigation/native";

messaging().setBackgroundMessageHandler(async remoteMessage => {
    await getNotification();
});

notifee.onBackgroundEvent(async ({type, detail}) => {
    const {notification, pressAction} = detail;

    if (type === EventType.PRESS) {
        console.log('User pressed an action with the id: ', pressAction.id);
        // navigate here
    }
    await notifee.cancelNotification(notification.id);
    console.log('background-event');
});

AppRegistry.registerComponent(appName, () => App);

RESTnotification.js

import messaging from '@react-native-firebase/messaging';
import notifee, {AndroidImportance, EventType} from "@notifee/react-native";
import AsyncStorage from "@react-native-community/async-storage";
import React from "react";

async function requestUserPermission() {
    const authStatus = await messaging().requestPermission();
    const enabled =
        authStatus === messaging.AuthorizationStatus.AUTHORIZED ||
        authStatus === messaging.AuthorizationStatus.PROVISIONAL;
    if (enabled) {
        console.log('Firebase authorization:', authStatus);
    }
}

export const checkToken = async () => {
    const fcmToken = await messaging().getToken();
    if (fcmToken) {
        console.log(fcmToken);
    }
    await AsyncStorage.setItem("fcmToken", fcmToken);
}

export default async function getNotification() {
    const channelId = await notifee.createChannel({
        id: 'important',
        name: 'Important Notifications',
        importance: AndroidImportance.HIGH,
    });

    await notifee.displayNotification({
        title: '<p><b>Verandering bij proces: {naam}</span></p></b></p>',
        body:
            '{user} heeft het proces {procesnaam} afgekeurd',
        data: {
            processId: '12345678'
        },
        android: {
            channelId: 'important',
            importance: AndroidImportance.HIGH,
            smallIcon: "ic_notification",
            //largeIcon: require('../../assets/images/apple-touch-icon.png'),
            pressAction: {
                id: 'default',
                launchActivity: 'default'
            },
        },
    });
}

checkToken();
requestUserPermission();

Are we overlooking something?

aksappy
  • 3,400
  • 3
  • 23
  • 49
ForEvigt
  • 43
  • 1
  • 4

1 Answers1

1

At the startup you can't use the hook useNavigation as it's still not built.

For this kind of use case, you need to use a different approach, the deep linking: https://reactnavigation.org/docs/deep-linking.

The basic flow is that you need to add a path on your notification data (for example myapp://user/profile) and move your notification handler inside the Deep Linking configuration.

For a practical example you can check this tutorial: https://medium.com/cybermonkey/deep-linking-push-notifications-with-react-navigation-5fce260ccca2

Francesco Clementi
  • 1,874
  • 4
  • 13
  • 28
  • Thanks for your help. We took a different approach now. We've been on this for a few hours now but I can't seem to get the deep linking working. Everything works just fine untill I try to open the app with the `npx uri-scheme` command to the page defined in the `deepLinksConf` does this occure because the StackNavigator is already been made in the App.js ? – ForEvigt Jul 21 '21 at 07:47
  • What problem are you getting? Do you have conditional navigators? How is your navigator defined? – Francesco Clementi Jul 21 '21 at 07:50
  • The app opens, but not on t he correct page. [This](https://prnt.sc/1durb3r) is the App.js where we define it. – ForEvigt Jul 21 '21 at 08:10
  • the problem could be the switch navigator. The deep link will try to open that url with the first navigator built (for your case it should be the starter one). When I use deep linking I always avoid to build the navigator stack before the check. The best approach is to have a function that check if the user is authenticated and then build directly the correct navigator. if you don't want to refactor your code, you could try with similar solution like this: https://stackoverflow.com/questions/54350991/react-navigation-deep-linking-with-authentication – Francesco Clementi Jul 21 '21 at 09:07
  • you can test this by leaving the app opened in the background (so the user is authenticated) and run npx uri-scheme – Francesco Clementi Jul 21 '21 at 09:10
  • We've refactored the navigation. Not that there was anything wrong with it but we couldn't complete the notification requirement. Deeplinking worked just fine. Many thanks! – ForEvigt Aug 02 '21 at 06:45
  • I'm very glad you did it! – Francesco Clementi Aug 02 '21 at 06:52