RORK LABEN
MAX — Rork MaxはiPhone・iPad・Apple Watch・Apple TV・Vision Pro向けにネイティブSwiftを生成し、2クリックでApp Store公開でき、Xcodeを必要としませんSTACK — 通常のRorkはReact Native(Expo)でクロスプラットフォームのモバイルアプリを作る位置づけ。用途に応じた使い分けが鍵ですFOCUS — BoltやLovableのようなWeb中心ツールと違い、RorkはiOS/Androidのネイティブアプリ生成に特化していますBUGS — 実利用レビューでは遭遇したバグの約70%を手動介入なしで解決、残り3割はエクスポート済みコードでの手修正が必要と報告されていますFUNDING — Rorkはa16z(Andreessen Horowitz)から$2.8Mを調達しましたPRICING — 無料で開始でき、有料プランは$25/月からです。まず触ってから判断できますMAX — Rork MaxはiPhone・iPad・Apple Watch・Apple TV・Vision Pro向けにネイティブSwiftを生成し、2クリックでApp Store公開でき、Xcodeを必要としませんSTACK — 通常のRorkはReact Native(Expo)でクロスプラットフォームのモバイルアプリを作る位置づけ。用途に応じた使い分けが鍵ですFOCUS — BoltやLovableのようなWeb中心ツールと違い、RorkはiOS/Androidのネイティブアプリ生成に特化していますBUGS — 実利用レビューでは遭遇したバグの約70%を手動介入なしで解決、残り3割はエクスポート済みコードでの手修正が必要と報告されていますFUNDING — Rorkはa16z(Andreessen Horowitz)から$2.8Mを調達しましたPRICING — 無料で開始でき、有料プランは$25/月からです。まず触ってから判断できます
記事一覧/開発ツール
開発ツール/2026-06-16上級

課金復元より先に広告を初期化したら、有料ユーザに一瞬広告が出た — Rork(Expo)アプリの起動順序設計

同意取得・ATT・広告初期化・課金復元・リモート設定を、起動の数百ミリ秒のあいだにどの順番で走らせるか。順序を1つ間違えるだけで、有料ユーザに広告が一瞬出たり、EEA で同意なしの計測が走ったりします。Rork で生成した Expo アプリの起動処理を1つのオーケストレータに畳み、競合を設計で潰す手順を実装メモとしてまとめます。

Rork414Expo84AdMob63ATT8起動シーケンスRevenueCat24状態管理8

プレミアム記事

Rork で生成した Expo アプリに広告と課金を入れたあと、TestFlight のレビュアーから「起動直後に一瞬だけバナーが出て、すぐ消える」という報告をもらったことがあります。課金済みのアカウントでした。再現は難しく、コールドスタート、つまりアプリを完全に終了してから初めて開いたときだけ起きます。

原因は機能のバグではなく、起動処理の順番でした。広告 SDK の初期化が先に終わり、最初のバナーが描画を始めたあとで、課金状態の復元が完了して「このユーザは広告非表示」と判定された。だから一瞬出てから消えたのです。

起動の数百ミリ秒のあいだには、同意取得・ATT の許可ダイアログ・広告 SDK の初期化・課金の復元・リモート設定の取得が同時に走ろうとします。それぞれは正しく実装されていても、走る順番が噛み合っていないと、お金を払った読者に広告を見せたり、EEA の読者に同意前の計測を走らせたりします。この記事は、その起動シーケンスを1つのオーケストレータに畳んで、順序の事故を設計で潰すための実装メモです。個人開発で6本のアプリを並行運用してきたなかで、ここを直列に整理し直したことが、起動まわりの不具合がいちばん減った転換点でした。

起動の数百ミリ秒で、何と何が競合するのか

コールドスタートで走らせたい初期化を並べると、だいたい次の5つになります。

  • ユーザ同意の取得(EEA なら UMP、GDPR/UMP の詳しい設定は別記事に譲ります)
  • ATT(App Tracking Transparency)の許可ダイアログ
  • 広告 SDK(AdMob / メディエーション)の初期化
  • 課金状態の復元(サブスク・買い切り・リワード時限解除)
  • リモート設定とフィーチャーフラグの取得

問題は、これらを useEffect のなかでそれぞれ独立に発火させると、終わる順番が実行ごとにばらつくことです。ネットワークが速い日は課金復元が先に終わり、遅い日は広告初期化が先に終わる。再現しないバグの典型で、私自身もしばらく「たまに起きる」で片付けていました。

順番がばらつくと困るのは、段と段のあいだに「依存」があるからです。広告は同意の後でなければ出してはいけない。広告を出すかどうかは課金状態が確定していなければ決められない。この依存を無視して並列に走らせると、依存先がまだ終わっていない一瞬に、依存元が動いてしまいます。冒頭のバナーちらつきは、まさにこの「課金復元が広告初期化に間に合わなかった一瞬」でした。

なぜ「同意 → ATT → 広告初期化」は崩せないのか

まず外せない直列の鎖が、同意と ATT と広告初期化の3つです。

EEA の読者に対しては、同意を取る前に計測(App Measurement)を走らせてはいけません。react-native-google-mobile-ads では、設定で delay_app_measurement_inittrue にして、最初の広告リクエストまで計測の初期化を遅らせます。これをしないと、同意ダイアログを出しているそばから計測が始まってしまいます。

ATT は iOS のトラッキング許可です。AdMob の管理画面で ATT メッセージを設定しておくと、UMP の同意フローが ATT ダイアログも続けて出してくれるので、自前で順番を組まなくてもこの2つは1つの流れにまとまります。重要なのは、この同意・ATT の流れが完了してから MobileAds().initialize() を呼ぶことです。順番が逆だと、同意の結果を読む前に SDK が初期化され、パーソナライズの可否が正しく反映されません。

最初に同意と ATT をまとめて取り、それが解決してから広告 SDK を初期化する。この鎖は短いですが、絶対に並列化してはいけない部分です。コードにすると次のようになります。

import mobileAds from "react-native-google-mobile-ads";
import {
  AdsConsent,
  AdsConsentStatus,
} from "react-native-google-mobile-ads";
 
// 同意 + ATT を1つの流れで解決する。
// AdMob 側に ATT メッセージを設定しておくと、UMP が ATT ダイアログも続けて出す。
async function gatherConsentThenInitAds(): Promise<void> {
  try {
    // 1) 同意情報を更新し、必要なら同意フォーム(と ATT)を提示する
    const consentInfo = await AdsConsent.requestInfoUpdate();
    if (
      consentInfo.isConsentFormAvailable &&
      consentInfo.status === AdsConsentStatus.REQUIRED
    ) {
      await AdsConsent.showForm();
    }
  } catch (e) {
    // 同意フローが失敗しても起動は止めない。
    // 広告はパーソナライズなし扱いで続行する。
    console.warn("[bootstrap] consent flow failed, continuing non-personalized", e);
  }
 
  // 2) 同意・ATT が解決してから、初めて広告 SDK を初期化する
  await mobileAds().initialize();
}

ここで try/catch を広く取っているのは意図的です。同意フローはユーザのネットワークや地域に依存して失敗しうるので、失敗しても起動そのものは止めず、広告を「パーソナライズなし」で続行させます。起動シーケンスでは、各段の失敗が全体を巻き込まないように、段ごとに握りつぶす範囲を決めておくのが要点です。

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

この記事の続きを読む

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

この記事で得られること
同意 → ATT → 広告初期化 → 課金復元 の順序を1つの bootstrap 関数に畳んだ、コピーして動かせる完全な実装コードを手に入れられる
「並列化してよい段」と「絶対に直列でなければならない段」を見分ける判断基準が分かり、起動時間を伸ばさずに順序事故を消せる
有料ユーザに広告が一瞬出る/EEA で同意前に計測が走る、という気づきにくい順序ミスを、再現条件つきで事前に塞げる
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

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

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

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

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

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

関連記事

開発ツール2026-06-15
「広告を消す理由」が3つに増えた日 — Rork アプリの広告非表示判定を1か所に畳む設計
課金していないはずの画面だけ広告が出る、あるいは課金済みの読者に広告が出てしまう。原因の多くは「広告を消す条件」がコードのあちこちに散らばっていることでした。サブスク・買い切り・リワード時限解除の3つを1つの状態に畳み、すべての広告表示を同じフックに通す設計を、個人開発で6本のアプリを運用してきた実装メモとしてまとめます。
開発ツール2026-06-15
電波が切れても操作を止めないアプリ設計 — 楽観的更新と、戻ってきたときの競合解決
Rork で作った Expo アプリを、地下鉄やエレベーターで電波が切れても操作が止まらないように設計します。画面を先に更新する楽観的更新と、通信が戻ったときに食い違いを解く競合解決を、動くコードで組み立てます。
開発ツール2026-06-14
Rork のサブスクを RevenueCat の Entitlement で組む — アクセス判定・Offering 駆動のペイウォール・復元の実装メモ
Rork(Expo)アプリの課金を RevenueCat で実装する際の設計メモです。Entitlement を唯一の真実とするアクセス判定、Offering 駆動でハードコードを避けるペイウォール、購入復元とリスナーの実装、サンドボックスで詰まりやすい点まで動くコードで整理します。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →