Question: Hi, I am using React Native with Expo SDK 51 and Expo Router. For notifications, I am using FCM v1. I receive notifications when my app is in the foreground, background, and even when it’s in a killed state. Additionally, when I click on a notification, it redirects me to the specific chat or post as expected.
However, I am facing an issue when my app is in a killed state. If I receive multiple notifications (e.g., 5 notifications) and try to open each one individually, nothing happens. But when I collapse all the notifications and then click on them, the app opens, although it fails to route to the intended destination.
Could someone please help me resolve this issue?
My project structure is like this:
app/
|-- index.jsx
|-- _layout.jsx
My index.jsx
is like this:
const index = () => {
return <></>;
};
export default index;
And this is my _layout.jsx
import * as Notifications from "expo-notifications";
import messaging from "@react-native-firebase/messaging";
import React, { useEffect, useState } from "react";
import { Stack, useRouter } from "expo-router";
Notifications.setNotificationHandler({
handleNotification: async () => {
const isOnChatPage = useAppStateStore.getState().isOnChatPage;
return {
shouldShowAlert: !isOnChatPage,
shouldPlaySound: true,
shouldSetBadge: false,
};
},
});
const HomeComponents = () => {
const navigation = useRouter();
const [response, setResponse] = useState({});
useEffect(() => {
const notificationOpenedAppListener = messaging().onNotificationOpenedApp(
(remoteMessage) => {
const screenType = remoteMessage?.data?.type;
const chatId = remoteMessage?.data?.chat_id;
const groupReplyId = remoteMessage?.data?.group_reply_id;
if (screenType === "personal_chat" && chatId) {
navigation.navigate(`/homescreen/chats/personalchat/${chatId}`);
} else if (screenType === "group_reply" && groupReplyId) {
navigation.navigate({
pathname: "/homescreen/chats/groups/replayshow",
params: { id: groupReplyId },
});
}
}
);
const getInitialNotificationListener = messaging()
.getInitialNotification()
.then((remoteMessage) => {
if (remoteMessage) {
const screenType = remoteMessage?.data?.type;
const chatId = remoteMessage?.data?.chat_id;
const groupReplyId = remoteMessage?.data?.group_reply_id;
if (screenType === "personal_chat" && chatId) {
navigation.navigate(`/homescreen/chats/personalchat/${chatId}`);
} else if (screenType === "group_reply" && groupReplyId) {
navigation.navigate({
pathname: "/homescreen/chats/groups/replayshow",
params: { id: groupReplyId },
});
}
}
});
const setBackgroundMessageHandlerListener = messaging().setBackgroundMessageHandler(async (remoteMessage) => {
setResponse(remoteMessage);
const chatId = remoteMessage.data.chat_id;
const screenType = remoteMessage.data.type;
const groupReplyId = remoteMessage?.data?.group_reply_id;
if (screenType === "personal_chat" && chatId) {
navigation.navigate(`/homescreen/chats/personalchat/${chatId}`);
}
if (screenType === "comment") {
navigation.navigate(`/homescreen/post`);
}
if (screenType === "group_reply" && groupReplyId) {
navigation.navigate({
pathname: "/homescreen/chats/groups/replayshow",
params: { id: groupReplyId },
});
}
// Manually trigger a local notification
await Notifications.scheduleNotificationAsync({
content: {
title: remoteMessage.notification.title,
body: remoteMessage.notification.body,
data: remoteMessage.data,
},
trigger: null, // Show immediately
});
});
const onMessageListener = messaging().onMessage(async (remoteMessage) => {
try {
setResponse(remoteMessage);
// Schedule notification to display
await Notifications.scheduleNotificationAsync({
content: {
title: remoteMessage.notification.title,
body: remoteMessage.notification.body,
data: remoteMessage.data,
},
trigger: null, // Show immediately
});
} catch (error) {
console.error("Error:", error);
}
});
// Handle notification clicks
const notificationResponseReceivedListener =
Notifications.addNotificationResponseReceivedListener(() => {
try {
console.log(response);
const screenType = response?.data?.type;
const chatId = response?.data?.chat_id;
const postId = response?.data?.post_id;
const groupReplyId = response?.data?.group_reply_id;
if (screenType === "personal_chat" && chatId) {
navigation.navigate(`/homescreen/chats/personalchat/${chatId}`);
}
if (screenType === "comment" && postId) {
navigation.navigate(`/homescreen/post/${postId}`);
}
if (screenType === "group_reply" && groupReplyId) {
navigation.navigate({
pathname: "/homescreen/chats/groups/replayshow",
params: { id: groupReplyId },
});
}
} catch (error) {
console.error("Notification click error:", error);
}
});
return () => {
notificationOpenedAppListener();
onMessageListener();
};
}, [navigation, response]);
return <></>;
};
export default HomeComponents;
Issues:
-
When the app is in a killed state and a new message arrives, clicking on the notification doesn’t open the app.
-
When clicking on the notification, I’m getting the error: “No task registered for key ReactNativeFirebaseMessagingHeadlessTask”.
Could someone please guide me on how to resolve these issues?