SDK 45
Development build (no Expo Go)
Hi! On Android, when receiving a notification and the app is in the background I get this error from the TaskManager:
TaskManager: Task “BACKGROUND-NOTIFICATION-TASK” failed:, [Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
- You might have mismatching versions of React and the renderer (such as React DOM)
- You might be breaking the Rules of Hooks
- You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.]
at node_modules/expo-task-manager/build/TaskManager.js:143:16 in eventEmitter.addListener$argument_1
at node_modules/expo-task-manager/build/TaskManager.js:133:57 in eventEmitter.addListener$argument_1
at node_modules/react-native/Libraries/vendor/emitter/_EventEmitter.js:150:10 in EventEmitter#emit
The task seems to be registered Ok:
Notifications.registerTaskAsync(BACKGROUND_NOTIFICATION_TASK); // returns null
TaskManager.isTaskRegisteredAsync(BACKGROUND_NOTIFICATION_TASK); returns true
TaskManager.getRegisteredTasksAsync() // returns Array [
Object {
"options": Object {},
"taskName": "BACKGROUND-NOTIFICATION-TASK",
"taskType": "remote-notification",
},
]
This is my partial setupNotifications.js file:
import { useEffect, useRef } from 'react';
import * as Device from 'expo-device';
import * as TaskManager from 'expo-task-manager';
import * as Notifications from 'expo-notifications';
import { AppState, Platform } from 'react-native';
import Constants from 'expo-constants';
const BACKGROUND_NOTIFICATION_TASK = 'BACKGROUND-NOTIFICATION-TASK';
TaskManager.defineTask(BACKGROUND_NOTIFICATION_TASK, ({ data, error, executionInfo }) => {
console.log('Received a notification in the background!', data);
});
Notifications.setNotificationHandler({
handleNotification: async () => ({
shouldShowAlert: true,
shouldPlaySound: true,
shouldSetBadge: false,
}),
});
export default function setupNotifications() {
const notificationListener = useRef();
const responseListener = useRef();
useEffect(() => {
registerBackgroundTask()
.then(() => null)
.catch(() => null);
registerForPushNotificationsAsync()
.then(() => null)
.catch(() => null);
// This listener is fired whenever a notification is received while the app is foregrounded
notificationListener.current = Notifications.addNotificationReceivedListener((notification) => {
console.log('Received a notification in the foreground!', notification);
// addNotification(notification);
});
// This listener is fired whenever a user taps on or interacts with a notification (works when app is foregrounded, backgrounded, or killed)
responseListener.current = Notifications.addNotificationResponseReceivedListener((response) => {
console.log('Received a notification response!', response);
if (AppState.currentState.match(/inactive|background/)) {
// addNotification(response.notification.request.content);
}
});
return () => {
Notifications.removeNotificationSubscription(notificationListener.current);
Notifications.removeNotificationSubscription(responseListener.current);
};
}, []);
...
...
...
}
In app.config.js I’ve added the corresponding plist
ios: {
…
…
infoPlist: {
UIBackgroundModes: [‘remote-notification’],
},
…
…
},