◉RORK LABEN
●GPT-6.1 SOL — Rork のモデルメニューに追加(09-29)。Low/Medium/High を選べ、Pro・Max に含まれます●SONNET 5.5 — UI づくりが得意で、Sonnet 5 より出力が速いモデルが選べます(09-28)●SDK 58 — Beta が 09/15 から。stable の案内はまだなく、Expo Go でのプロジェクト実行は 09/03 からログインが必要です●WIDGET — iOS のウィジェットが本番ビルドだけ真っ黒になる原因を追った報告が出ています●OBSERVE — EAS Observe がネイティブクラッシュも記録します(SDK 57.0.21 以降・10/07)●NEW — 起動広告が、背面から戻った回にしか出ていませんでした。「前面に戻った」合図が、…●GPT-6.1 SOL — Rork のモデルメニューに追加(09-29)。Low/Medium/High を選べ、Pro・Max に含まれます●SONNET 5.5 — UI づくりが得意で、Sonnet 5 より出力が速いモデルが選べます(09-28)●SDK 58 — Beta が 09/15 から。stable の案内はまだなく、Expo Go でのプロジェクト実行は 09/03 からログインが必要です●WIDGET — iOS のウィジェットが本番ビルドだけ真っ黒になる原因を追った報告が出ています●OBSERVE — EAS Observe がネイティブクラッシュも記録します(SDK 57.0.21 以降・10/07)●NEW — 起動広告が、背面から戻った回にしか出ていませんでした。「前面に戻った」合図が、…
記事一覧/開発ツール
⬡ 開発ツール/2026-07-17上級

許可を聞かずに通知を届ける — Rork アプリの provisional 認可と、Expo の定番コードが握りつぶすもの

iOS には許可ダイアログを出さずに通知を配り始める provisional 認可があります。ところが Expo 公式が載せている定番の登録コードをそのまま使うと、provisional で通った端末が「拒否」として扱われ、避けたかったはずのダイアログが出ます。granted が false になる仕組みから、5値で許可状態を扱うフック、静かな配信を前提にした通知設計、昇格を求める判断、計測の分離までを実装込みで整理しました。

Rork583Expo219expo-notifications7プッシュ通知20リテンション17

✦ プレミアム記事

壁紙アプリの新しい配信機能を入れたとき、通知の許可率が思ったほど伸びませんでした。ソフトアスク画面は作ってあり、価値が伝わる場面まで待ってから聞いていたので、設計としては悪くないはずでした。それでも「まだこのアプリが何を送ってくるか分からない」段階で判断を迫っている構図は変わっていなかったのです。

そこで思い出したのが provisional 認可でした。iOS 12 から入っている仕組みで、許可ダイアログを一切出さずに通知を配り始められます。ユーザーは通知そのものを見てから、続けるか止めるかを決めます。聞き方を工夫するのではなく、聞く順番をひっくり返すのです。私はこの発想の方が誠実だと感じました。

ただ、実装に入って最初に踏んだのは、Expo 公式ドキュメントに載っている登録コードそのものが罠になっている、という落とし穴でした。

許可を聞かない、という第三の選択肢

通知の opt-in をめぐる打ち手は、これまで2つでした。起動直後に OS ダイアログを撃つか、自前のソフトアスク画面を一枚挟んでから撃つか。後者が優れているのは間違いありませんが、どちらも「まだ届いていない通知」の価値をユーザーに想像させている点では同じです。

provisional 認可は前提が違います。UNAuthorizationOptions に .provisional を足すと、システムはダイアログを出しません。通知は静かに配信され、通知センターの中だけに現れます。そこに「残す」「オフにする」のボタンが並び、ユーザーは実物を見たうえで判断します。

Apple がこれを用意した理由は明快です。どんな通知が来るのかを見ないまま、通知を受け取るかどうかを情報に基づいて決めることは、そもそもユーザーには不可能だからです。

Expo からは allowProvisional で要求します。

import * as Notifications from 'expo-notifications';
 
const settings = await Notifications.requestPermissionsAsync({
  ios: {
    allowAlert: true,
    allowSound: true,
    allowBadge: true,
    allowProvisional: true,
  },
});

このコードはダイアログを出しません。ユーザーの操作を待たずに解決し、通知の送信が始められる状態になります。ここまでは公式ドキュメントの通りです。

provisional で実際に手に入るもの、手に入らないもの

ここを曖昧にしたまま実装すると、あとで通知が「届いているのに誰も見ていない」という状態を、原因不明のまま抱えることになります。要求したオプションが全部通るわけではないからです。

配信面 provisional full(AUTHORIZED)
通知センターへの表示 ○ ○
バナー表示 × ○
ロック画面への表示 × ○
サウンド × ○
アプリアイコンのバッジ ×(要求しても付与されない) ○
許可ダイアログ 出ない 出る
timeSensitive による割り込み × ○

バッジの扱いは特に注意が必要です。上のコードでは allowBadge: true を要求していますが、provisional で通った端末ではバッジは付きません。設定アプリの通知詳細を開くと、通知センターへの表示は許可されている一方、バッジの項目だけが許可されていない状態が確認できます。要求は通っているのに権限は下りていない、という食い違いが起きます。

つまり、未読件数をバッジで伝える設計をしているなら、provisional コホートに対してその導線は最初から死んでいます。setBadgeCountAsync は例外を投げずに、ただ何も起きません。私はここで半日を溶かしました。エラーが出ないバグは、出るバグより厄介です。

timeSensitive も効きません。緊急性の高い通知を割り込ませたいなら、それは provisional の外側にある機能です。

✦

ここまでお読みいただきありがとうございます。

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
✦provisional 認可では expo-notifications の granted が false を返すため、Expo 公式の登録スニペットをそのまま使うと再リクエストが走り、避けたかった許可ダイアログが出てしまう仕組みと、その回避実装
✦provisional で実際に手に入る配信面と手に入らない配信面(バッジは要求しても付与されない・ロック画面とバナーには出ない)を実機の設定画面と対応づけて整理した判断表
✦許可状態を5値で扱うフック、静かな配信を前提にした通知本文の設計、full への昇格を求めるタイミング判定、provisional コホートを分離した計測設計までの実装一式
Stripe による安全な決済 · いつでもキャンセル可能
✦

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

お読みいただきありがとうございます

Rork Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • ✦コピー&ペーストで使える実装コード付き
  • ✦毎日新しい上級ガイドを追加
  • ✦¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

関連記事

⬡ 開発ツール2026-10-15
EXPO_PUBLIC_ の値が、開発では読めて本番だけ undefined になる書き方を、変換結果で見分けます
API の URL が開発中は読めるのに、ビルドした途端に undefined になる。原因は process.env の書き方でした。babel-preset-expo の変換結果を開発・本番で並べ、置き換わる書き方と残ってしまう書き方を表にしました。
⬡ 開発ツール2026-10-13
リリース前に、書き出した Expo バンドルの中から自分の鍵を探してみる
ソースに鍵がなくても、出来上がったアプリの中に鍵が残ることがあります。Expo SDK 57 で実際に expo export を実行し、バンドルの中身を grep と 60 行ほどの Node スクリプトで調べて、見つかる鍵と見つからない鍵の違いを確かめました。
⬡ 開発ツール2026-10-07
日本語の見出しだけ太字にならない — Android で fontWeight が効かないときの切り分けと直し方
Rork で作ったアプリで、iPhone では太字なのに Android では日本語の見出しが細いままになる症状の切り分け記事です。原因の見分け方、fontFamily を重みごとに分ける直し方、確認用コードを載せています。