◉RORK LABEN
●GPT-6.1 SOL — Rork のモデルメニューに追加(09-29)。Low/Medium/High を選べ、Pro・Max に含まれます●SONNET 5.5 — UI づくりが得意で、Sonnet 5 より出力が速いモデルが選べます(09-28)●SONNET 4.5 — Claude API での提供終了は 11/30、残り27日。API 連携を足したアプリは移行先の確認を●SDK 58 — React Native 0.88 に更新されました。Android のリリース版で R8 が既定オンになり、iOS は SceneDelegate を生成します●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)●SONNET 4.5 — Claude API での提供終了は 11/30、残り27日。API 連携を足したアプリは移行先の確認を●SDK 58 — React Native 0.88 に更新されました。Android のリリース版で R8 が既定オンになり、iOS は SceneDelegate を生成します●OBSERVE — EAS Observe がネイティブクラッシュも記録します(SDK 57.0.21 以降・10/07)●NEW — 起動広告が、背面から戻った回にしか出ていませんでした。「前面に戻った」合図が、…
記事一覧/開発ツール
⬡ 開発ツール/2026-06-15上級

「広告を消す理由」が3つに増えた日 — Rork アプリの広告非表示判定を1か所に畳む設計

課金していないはずの画面だけ広告が出る、あるいは課金済みの読者に広告が出てしまう。原因の多くは「広告を消す条件」がコードのあちこちに散らばっていることでした。サブスク・買い切り・リワード時限解除の3つを1つの状態に畳み、すべての広告表示を同じフックに通す設計を、個人開発で6本のアプリを運用してきた実装メモとしてまとめます。

Rork611Expo234AdMob75RevenueCat30状態管理12Zustand4収益化70

✦ プレミアム記事

課金しているのに広告が出る、という問い合わせを App Store のレビューで受けたことがあります。調べてみると、課金状態そのものは正しく取れていて、ホーム画面では広告がきちんと消えていました。広告が残っていたのは、後から追加した「お気に入り一覧」という新しい画面だけでした。

原因はすぐに分かりました。その画面を実装したとき、私は広告を出すかどうかを if (!isSubscribed) という1行で判定していたのです。ところが私のアプリには、その時点で「広告を消す理由」がサブスクだけでなく、買い切りの広告解除と、リワード広告を見ると一定時間広告が消える時限解除の、合計3つありました。新しい画面はサブスクしか見ていなかったので、買い切りユーザにだけ広告が出ていたわけです。

判定条件が1つのうちは if (!isSubscribed) で困りません。問題は、収益化の都合で「広告を消す理由」が静かに増えていったときに、過去に書いた判定が置き去りになることです。この記事は、その散らばりを根本から断つために、広告非表示の判定を1つの状態に畳んで全画面から同じ入口を通す設計を、Rork で生成した Expo アプリを前提に書いていきます。

「広告を消す理由」は気づくと増えている

最初にリリースしたとき、私のアプリには広告解除の手段が買い切りの1つしかありませんでした。半年後にサブスクを足し、さらにリテンション施策としてリワード広告による時限解除を入れました。それぞれは別の時期に、別の収益化の判断で追加したものです。

ここで起きるのが、判定ロジックの分散です。サブスクを足したときに広告まわりのコードを直し、リワードを足したときにまた直す。直す範囲は毎回「広告を出している場所」全部のはずなのに、人間の記憶は当てになりません。画面が10を超えたあたりから、どこかが必ず取りこぼされます。

しかもこの取りこぼしは2方向に効きます。広告を消し忘れれば、お金を払った読者に広告を見せてしまい、返金やレビュー低下に直結します。逆に消しすぎれば、無料ユーザにも広告が出ず、収益がそのぶん消えます。どちらも静かに進行するので、気づくのはたいてい数字が動いてからです。

つまり本当の問題は「判定が間違っている」ことではなく、「同じ判定が複数箇所に書かれていて、片方だけ更新される」ことにあります。直すべきは個々の if ではなく、判定を1か所に集める構造のほうです。

3つの理由を1つの状態に畳む

まず、広告を消す理由を型として明示します。Rork が吐き出すコードは画面ごとにロジックが閉じがちなので、ここを共有モジュールに切り出すことが第一歩です。

// lib/adFree/types.ts
export type AdFreeReason =
  | 'subscription'   // 有効なサブスクリプション
  | 'lifetime'       // 買い切りの広告解除
  | 'reward'         // リワード広告による時限解除(期限あり)
  | null;            // 広告を出す(解除なし)
 
export interface AdFreeState {
  reason: AdFreeReason;
  // reward の場合のみ意味を持つ。エポックミリ秒。
  rewardExpiresAt: number | null;
}

ポイントは、isAdFree: boolean という真偽値を最初から持たせないことです。真偽値だけにしてしまうと、「なぜ広告が消えているのか」が後から分からなくなり、リワードの期限が来たのに消えたままといった不具合の原因追跡ができません。理由を保持しておくと、ログにそのまま流せますし、UI 側で「あと32分は広告が消えています」のような表示にも使えます。

3つの理由には優先順位があります。私は次の順で評価しています。

  1. lifetime(買い切り)— 一度解除したら恒久。最優先で、他の状態が何であっても広告は出さない
  2. subscription(サブスク)— 有効期間中は広告を出さない
  3. reward(時限解除)— 期限内のときだけ広告を出さない

この順序が効くのは、たとえば「買い切り済みのユーザがうっかりリワード広告を見てしまった」ような場合です。買い切りが最優先なので、リワードの期限管理に引きずられて挙動が変わることがありません。判定を1か所に集める価値は、こうした優先順位を1回だけ正しく書けば済む点にもあります。

✦

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

この記事の続きを読む

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

この記事で得られること
✦サブスク・買い切り・リワード時限解除の3つを優先順位つきで合成する useAdFree セレクタの完全な実装コード
✦時限解除の期限切れを画面に追従させる、1秒間隔ではなく『次の期限ちょうど』に発火させるタイマー設計
✦端末時刻を巻き戻すと広告が無限に消える不具合を、サーバ時刻の単調増加チェックで塞いだ実測手順
Stripe による安全な決済 · いつでもキャンセル可能
✦

この記事を購入する

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

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

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

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

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

関連記事

⬡ 開発ツール2026-06-12
Rork 製アプリに開発者デバッグメニューを実装する — 広告・課金・Remote Config の検証をリリース前に終わらせる設計
リリースビルドでしか再現しない広告・課金・Remote Config の不具合に毎回本番で向き合うのは消耗します。壁紙アプリ6本の運用で固まった、ストア提出ビルドには存在ごと残さない開発者デバッグメニューの設計と実装を、動くコードと落とし穴付きで共有します。
⬡ 開発ツール2026-04-24
Rork × AdMob UMP × ATT 同意管理の本番実装ガイド — グローバル配信で収益を落とさないための設計パターン
AdMobのUMPとATTをRorkアプリに正しく組み込み、GDPRに準拠しながら収益を落とさないための本番実装パターンです。3つの同意レイヤーと初期化順序、地域判定と分岐、同意状態のSDKへの伝播、設定画面からの撤回UI、詰まりやすい落とし穴6つを解説します。
⟐ ビジネス2026-04-04
Rork アプリの収益設計 — 広告と課金が食い合う地点をどう避けるか
Rork で作ったアプリに AdMob・サブスクリプション・単発課金をどう重ねるか。広告と課金のカニバリゼーションを設計で避ける方法、RevenueCat の Entitlement 中心設計、ペイウォールを出すタイミングの決め方を実装コードとともにまとめました。