푸쉬 알림이 발생했을 때 어플리케이션이 스마트폰에서 완전히 종료된 상태에서는 푸쉬알림 터치 시 원하는 화면으로 정확하게 이동되지 않는 문제가 발생하였습니다.
예시)
1. 내가 작성한 게시글에 댓글이 달렸다는 푸쉬알림 발생
2. 푸쉬알림 터치 시 내가 작성한 게시글 화면으로 이동해야하나 어플리케이션이 실행된 후 홈화면에 그대로 유지됨
어플리케이션을 이용중이거나 백그라운드에서 어플리케이션이 실행중인 상황에서는 푸쉬알림 터치 시 원하는 화면으로 정확하게 이동
아래의 커스텀훅은 OneSIgnal SDK에서 제공해주는 메소드를 사용하여 푸쉬알림 선택시의 스크린 이동에 대한 행동의 정의해주는 커스텀훅입니다.
export const useOneSignalPushAlarmInit = () => {
const { navigate } = useAppNavigation();
useEffect(() => {
// Method for handling notifications opened
OneSignal.setNotificationOpenedHandler(({ notification }) => {
const additionalData = notification.additionalData as AdditionalData;
switch (additionalData.type) {
case PushAlarmTypes.SOME_STATE0:
navigate(어디론가 슈슝 이동~)
break;
case PushAlarmTypes.SOME_STATE1:
case PushAlarmTypes.SOME_STATE2:
case PushAlarmTypes.SOME_STATE3:
case PushAlarmTypes.SOME_STATE4:
case PushAlarmTypes.SOME_STATE5:
navigate(어디론가 슈슝 이동~)
break;
case PushAlarmTypes.SOME_STATE6:
navigate(어디론가 슈슝 이동~)
break;
case PushAlarmTypes.SOME_STATE7:
navigate(어디론가 슈슝 이동~)
break;
default:
return;
}
});
}, [navigate]);
};
이 커스텀훅의 navigate 함수를 실행시키기 위해선 이미 네비게이션 구조와 설정이 모두 완성되어있어야 합니다.
허나 문제의 상황에선 네비게이션 설정이 모두 완료되기 전 푸쉬알림이 의도하는 스크린으로 이동시키고자 하였고 그로인해 홈스크린에서 머무르게 된 것입니다.
ERROR The action 'NAVIGATE' with payload {"name":"CommunityPostScreen","params":{"feedPostCode":"codecodecodecodecode"}} was not handled by any navigator.
Do you have a screen named 'CommunityPostScreen'?
If you're trying to navigate to a screen in a nested navigator, see https://reactnavigation.org/docs/nesting-navigators#navigating-to-a-screen-in-a-nested-navigator.
This is a development-only warning and won't be shown in production.
NavigationContainer는 리액트 네비게이션의 루트 컴포넌트로, 네비게이션의 상태와 구조를 관리합니다. NavigationContainer가 마운트 될 때, 내부의 네비게이션 구조 (예: Stack Navigator, Tab Navigator 등)와 설정은 초기화됩니다.
즉, NavigationContainer가 마운트 완료된 후 navigate 함수를 실행해주니 문제는 해결되었습니다.
useOneSignalPushAlarmInit 커스텀훅은 기존 useAppInitializationCheckEffect라는 커스텀훅 안에서 실행되었고 useAppInitializationCheckEffect 커스텀훅은 총 2군데위치에서 실행되었습니다.
그 2곳의 위치는 로그인 스크린 + 홈 스크린 이었습니다.
허나 우리의 네비게이트 구조상 로그인이 완료되기 전 스크린들과 로그인이 완료된 후의 스크린들은 각기 다른 Stack Group에 소속되어있고 로그인 상태에 따라 마운트 여부를 결정합니다.
<RootStack.Navigator
screenOptions={{
statusBarColor: isAndroid ? background.main : undefined,
statusBarStyle: 'dark',
}}
>
{isLoggedIn ? (
<RootStack.Group>
<RootStack.Screen
name={BottomNavigatorScreenNames.Root}
component={BottomNavigator}
options={{ headerShown: false }}
/>
{getConsultationStackGroup()}
{getTranslationStackGroup()}
{getHealthScreeningStackGroup()}
{getCommunityStackGroup()}
{getSettingStackGroup()}
{getUserStackGroup()}
</RootStack.Group>
) : (
<>{getAuthStackGroup()}</>
)}
</RootStack.Navigator>
하여 로그인 스크린에서 navigate(결과지해석스크린) 함수를 실행할 경우 네비게이션 설정에는 없는 스크린으로 이동하라는 명령이 전달되기에 올바르게 명령이 실행되지 않았습니다.
useOneSignalPushAlarmInit 함수를 useAppInitializationCheckEffect 커스텀훅안에서 제거한 후
홈스크린에서만 초기화를 실행해주는 useHomeScreenEffect라는 커스텀훅으로 이동시켜주었습니다.
export const useHomeScreenEffect = () => {
useAppInitializationCheckEffect();
useCheckHasNicknameEffect();
useHomePrefetchingEffect();
useOneSignalPushAlarmInit();
};
푸쉬알림 초기화 함수는 로그인 전 단계에서는 실행시킬 필요가 없기에
로그인 완료된 후 첫 이니셜 라우트인 홈스크린에서만 실행되면 됩니다.
하여 로그인 스크린에서도 사용되는 useAppInitializationCheckEffect 커스텀훅에서 제거해주고
별도의 홈스크린만을 위한 초기화 커스텀훅인 useHomeScreenEffect 커스텀훅으로 옮겨주었습니다.
로그인 후 스택그룹안에서 navigate(결과지해석)을 실행하게되면 이제는 네비게이션 구조안에 결과지해석 스크린이 존재하므로 에러없이 정상동작함을 확인하였습니다.