-
Notifications
You must be signed in to change notification settings - Fork 273
Description
Hi. I am having an issue with quick actions on iOS only. I have two quick actions on a push notification, one opens the app in the foreground, the other does not. When clicking the quick action that launches the app, from an app killed state, the press event is lost and the background nor foreground event handlers are ever triggered. This is an issue because our app relies on a mutation firing off based on the quick action selected, but as of now, the app just launches and never reaches the logic in notifee.onBackgroundEvent or notifee.onForegroundEvent().
Quick actions work fine when the app is open or simply backgrounded (i.e., not force quit from the app switcher) because the notifee.onForegroundEvent() handler gets called.
Our project is an Expo managed app, with the following dependencies:
"expo": "~50.0.17",
"@notifee/react-native": "^7.8.2",
"@react-native-firebase/app": "19.0.1",
"@react-native-firebase/messaging": "19.0.1"
Implementation
index.js
import "@expo/metro-runtime";
import notifee, { EventType } from "@notifee/react-native";
import messaging from "@react-native-firebase/messaging";
import { App } from "expo-router/build/qualified-entry";
import { renderRootComponent } from "expo-router/build/renderRootComponent";
messaging().onMessage(onMessageReceived);
messaging().setBackgroundMessageHandler(onMessageReceived);
notifee.onBackgroundEvent(async ({ type, detail }) => {
if (type === EventType.PRESS) {
console.log("Regular pressed");
} else if (type === EventType.ACTION_PRESS) {
console.log("Action pressed");
}
notifee.cancelDisplayedNotifications();
});
renderRootComponent(App);_layout.tsx (located at project-name/app/_layout.tsx)
import notifee, { EventType } from "@notifee/react-native";
import * as SplashScreen from "expo-splash-screen";
import React, { ReactElement, useCallback, useState } from "react";
import { useOnMount, useOnUpdate } from "@/util/hooks";
const SPLASH_SCREEN_TIMEOUT = 2000;
SplashScreen.preventAutoHideAsync();
export type AppLayoutType = object;
const RootView = styled.View`
height: 100%;
width: 100%;
`;
const AppLayout: React.FC<AppLayoutType> = (): ReactElement | null => {
const [appIsReady, setAppIsReady] = useState<boolean>(false);
useOnMount(async () => {
try {
await new Promise((resolve) =>
setTimeout(resolve, SPLASH_SCREEN_TIMEOUT),
);
} catch (error) {
console.error(error);
}
setAppIsReady(true);
return notifee.onForegroundEvent(async ({ type, detail }) => {
const { notification } = detail;
if (type === EventType.PRESS) {
console.log("Regular press");
} else if (type === EventType.ACTION_PRESS) {
console.log("Action press");
}
});
});
const onLayoutRootView = useCallback(async () => {
if (appIsReady) {
await SplashScreen.hideAsync();
}
}, [appIsReady]);
if (!appIsReady) {
return null;
}
return (
<SafeAreaProvider>
...other providers
<RootView onLayout={onLayoutRootView}>
<Stack />
</RootView>
</SafeAreaProvider>
);
};
export default AppLayout;