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>
...略)
});
実際に動作させると、以下のようになりました。