以下のようなユーザーにレビューを依頼するための仕組みを作ります。
ライブラリをインストール
shell
npx expo install expo-store-review expo-linking
日付の比較、次回レビュー日を保存するためのライブラリもインストールします。
shell
npx expo install dayjs @react-native-async-storage/async-storage
レビューを依頼する hooks を作成
useStoreReview.ts
import AsyncStorage from '@react-native-async-storage/async-storage';
import dayjs, { type Dayjs } from 'dayjs';
import * as StoreReview from 'expo-store-review';
/** レビュー依頼の頻度(何日おきにレビュー依頼するか) */
const REVIEW_PERIOD_BY_DATE = 3;
/** リセット用のレビュー日を何日前にするか */
const RESET_REVIEW_DATE_BY_DATE = -1;
export default function useStoreReview() {
/**
* 次回レビュー日を取得する。取得できなかった場合は初回起動である。
*/
const getNextReviewDate = async () => {
return await AsyncStorage.getItem('nextReviewDate');
};
/**
* 次回のレビュー依頼日を取得する
* @param {number} period 何日後か
*/
const getNextReviewDateByPeriod = (period: number) => {
return dayjs().add(period, 'day');
};
/**
* 次回のレビュー依頼日を保存する
*/
const updateNextReviewDate = async (nextReviewDate: Dayjs) => {
await AsyncStorage.setItem('nextReviewDate', nextReviewDate.format('YYYY-MM-DD'));
};
/**
* 開発時の動作検証のため、レビュー依頼日をリセットする
*/
const resetNextReviewDate = async () => {
const nextReviewDate = getNextReviewDateByPeriod(RESET_REVIEW_DATE_BY_DATE);
await AsyncStorage.setItem('nextReviewDate', nextReviewDate.format('YYYY-MM-DD'));
};
/**
* 初回起動時にレビュー依頼日を保存する
*/
const setInitialNextReviewDate = async () => {
const initialNextReviewDate = getNextReviewDateByPeriod(REVIEW_PERIOD_BY_DATE);
await updateNextReviewDate(initialNextReviewDate);
};
/**
* 今日がレビュー依頼日に到達しているかどうかを判定する
*/
const doesReachedNextReviewDate = async () => {
const nextReviewDate = await getNextReviewDate();
if (nextReviewDate != null) {
return dayjs().isAfter(dayjs(nextReviewDate, 'YYYY-MM-DD'));
}
return false;
};
const developmentRequestReview = async () => {
try {
const nextReviewDate = await getNextReviewDate();
if (nextReviewDate == null) {
await setInitialNextReviewDate();
return;
}
// 開発用のため、レビュー依頼日をリセットする
await resetNextReviewDate();
const reachedNextReviewDate = await doesReachedNextReviewDate();
const isReviewAvailable = await StoreReview.isAvailableAsync();
if (isReviewAvailable && reachedNextReviewDate) {
await StoreReview.requestReview();
const nextReviewDate = getNextReviewDateByPeriod(REVIEW_PERIOD_BY_DATE);
await updateNextReviewDate(nextReviewDate);
}
} catch (error) {
console.log(error);
}
return `レビューを依頼しました。`;
};
const requestReview = async () => {
try {
const nextReviewDate = await getNextReviewDate();
if (nextReviewDate == null) {
await setInitialNextReviewDate();
return;
}
const reachedNextReviewDate = await doesReachedNextReviewDate();
const isReviewAvailable = await StoreReview.isAvailableAsync();
if (isReviewAvailable && reachedNextReviewDate) {
await StoreReview.requestReview();
const nextReviewDate = getNextReviewDateByPeriod(REVIEW_PERIOD_BY_DATE);
await updateNextReviewDate(nextReviewDate);
}
} catch (error) {
console.log(error);
}
return `レビューを依頼しました。`;
};
return { developmentRequestReview, requestReview };
}
App.tsx で hooks を使う
App.tsx
export default function App() {
const { requestReview } = useStoreReview();
useEffect(() => {
requestReview()
.then((result) => {
console.log(result);
})
.catch((error) => {
console.log(error);
});
}, []);
return (
{/** 省略 */}
);
}
参考
app.json に appStoreUrl
を設定する
ルートディレクトリにある app.json
に appStoreUrl
を設定します。以下は iOS の例です。
app.json
"ios": {
"supportsTablet": false,
"appStoreUrl": "https://apps.apple.com/app/id1539375279"
},
アプリのIDは App Store を開けばわかります。 /us/
のように、USAのリージョンコードが振られているように見えますが、一応、日本で開くと ja
にリダイレクトされるっぽかったです。ちょっとここは自信がないので、実際のプロダクトで動作確認後に追記します。
iOS アプリの ID の調べ方の参考リンクは以下です。
5回保存したらレビューを依頼する(レビューのタイミングをイベント契機にする)
この記事では単純に起動回数をトリガにしましたが、「保存を5回実行したらレビュー依頼する」などの方が、より柔軟にレビューを出すユーザーを厳選できます。
以下の記事によりシンプルな方法をまとめました。