PUsh通知から指定の画面に遷移させる機能を作成したかったので実装
Pull Request
実装
まず、以下を参考にReact NavigationでDeep Linkを実装
https://reactnavigation.org/docs/deep-linking
import React from 'react'; import { NavigationContainer } from '@react-navigation/native'; import * as Notifications from 'expo-notifications'; import { createStackNavigator } from '@react-navigation/stack'; import * as Linking from 'expo-linking'; import Home, { HomeScreenOption } from 'components/pages/Home'; import theme from 'config/theme'; const Stack = createStackNavigator(); const prefix = Linking.createURL('/'); const WithProvider = () => { return ( <NavigationContainer linking={{ prefixes: [prefix], subscribe(listener) { const onReceiveURL = ({ url }: { url: string }) => { listener(url); }; Linking.addEventListener('url', onReceiveURL); const subscription = Notifications.addNotificationResponseReceivedListener( (response) => { const url = response.notification.request.content.data?.urlScheme ?? ''; if (url !== '') { listener(`${prefix}${url}`); } } ); return () => { Linking.removeEventListener('url', onReceiveURL); subscription.remove(); }; }, }} > ...略)
Expoはクライアントアプリで実行時とスタンドアローンアプリでschemaが変わってしまうので、expo-linkingを使用して指定する
const prefix = Linking.createURL('/')
今回は複雑なパラメータ設定が無いので設定していませんが、もしパラメータが必要な場合は、Configuring linksから設定可能です。
上記の実装が完了したら、以下のコマンドでDeep Linkが行えるか確認できます。
$ npx uri-scheme open exp://127.0.0.1:19000/--/MyPage --ios
MyPageはNavigationのScreen Nameになるので、実行してマイページ画面に遷移できれば正常に設定できています。
続いてPush通知からの遷移の実装です。以下が対象のコードです。(以下を参考に実装)
https://reactnavigation.org/docs/deep-linking/#third-party-integrations
subscribe(listener) { const onReceiveURL = ({ url }: { url: string }) => { listener(url); }; Linking.addEventListener('url', onReceiveURL); const subscription = Notifications.addNotificationResponseReceivedListener( (response) => { const url = response.notification.request.content.data?.urlScheme ?? ''; if (url !== '') { listener(`${prefix}${url}`); } } ); return () => { Linking.removeEventListener('url', onReceiveURL); subscription.remove(); }; },
Push通知のdataにurlSchemeのパラメータが設定している場合は、画面遷移するように実装されています。
const url = response.notification.request.content.data?.urlScheme ?? ''; if (url !== '') { listener(`${prefix}${url}`); }
これで実装は完了です。 最後にデバッグ用にローカル Push通知にurlSchemeのパラメータを設定して想定通りに動作しているか確認します。
■ src/components/organisms/Debug/Debug.tsx
import React, { memo, useCallback, useState } from 'react'; import { StyleSheet, TouchableOpacity, Alert } from 'react-native'; import * as Notifications from 'expo-notifications'; ...略) type Props = {}; const Menu: React.FC<Props> = () => { const onLocalPushNotification = useCallback(async () => { const { status: existingStatus, } = await Notifications.getPermissionsAsync(); let finalStatus = existingStatus; if (existingStatus !== 'granted') { const { status } = await Notifications.requestPermissionsAsync(); finalStatus = status; } if (finalStatus !== 'granted') { return false; } Notifications.scheduleNotificationAsync({ content: { body: 'Push通知テスト', data: { urlScheme: 'MyPage', }, }, trigger: { seconds: 3, }, }); Alert.alert('3秒後に通知を設定しました'); }, []); return ( <TouchableOpacity onPress={onLocalPushNotification}> <View> <Text fontFamily="NotoSansJP-Bold">ローカルPush通知テスト</Text> </View> </TouchableOpacity> ...略) });
実際に動作させると、以下のようになりました。