この記事についてClaude(Anthropic)との共同編集により作成されました。
要約
- 自作アプリを開発者自身がプレミアム状態で使いたいとき、RevenueCatのGranted Entitlements(Grant機能)を使えば課金なしで権限を付与できる
- 前提として、アプリ内で自分のapp user IDをタップでコピーできるようにしておく。匿名IDは手打ちできない長さなので、これがないと毎回つらい
- RevenueCatの公式モバイルアプリを同じ端末に入れておくと、IDコピー→検索→Grantが端末の中だけで完結する
- DurationはA day(1日)など短めが基本。プレミアムを外した状態のテストがしたくなったとき、長い期限は邪魔になる
- テスト運用が安定してきたら長めに切り替えればいい。Lifetimeにする自然なタイミングは自分で選べる
自作アプリにサブスク課金を入れると、地味だが避けられない問題にぶつかる。開発者の自分は、課金せずにプレミアム状態でアプリを使いたい。
ストアのサンドボックス環境でテスト購入する方法はもちろんあるが、あれは購入フローそのものの検証には向いていても、「本番ビルドを普段使いしながらプレミアム機能の使い勝手を確かめる」という日常的な用途には大げさすぎる。かといって、デバッグビルドだけプレミアム判定を強制的にtrueにするようなコードを仕込むと、本番と条件が変わってしまい、それはそれでテストにならない。
この記事では、先日リリースした縦書きブラウザアプリtanzakuで実際に運用している方法を紹介する。RevenueCatのGrant機能(Granted Entitlements)を使い、自分のアカウントにだけプレミアム権限を無料で付与するやり方だ。手順そのものは公式ドキュメントにも書いてあるのだが、個人開発の実運用で効いてくるのは周辺の小技のほうだった。具体的には「アプリ内でIDをタップコピーできるようにしておく」ことと「Durationを短めに設定する」ことの2つ。実体験から得た知見として、その理由も含めて書き残しておく。
なお、そもそもなぜRevenueCatを選んだのかは以前の比較記事にまとめている。
全体像 — 3ステップで自分にプレミアムを付ける
やることはシンプルで、次の3ステップに分かれる。
- アプリ内で自分のapp user IDをコピーする(そのための実装を仕込んでおく)
- RevenueCatのモバイルアプリでそのIDを検索し、自分のCustomer profileを開く
- EntitlementsカードのGrantで、付けたいentitlementを短めのDurationで付与する
Grant機能で付与した権限(Granted Entitlements)はRevenueCat側で完結する仕組みで、App StoreやGoogle Playの課金システムとは独立している。請求が発生することも、ストアのサブスクリプションに変換されることもない^1。開発者が自分に権限を付ける用途にはちょうどいい。
以下、各ステップの中身と、実運用でハマったポイントを順に見ていく。
ステップ1の前提 — IDをタップでコピーできるようにしておく
RevenueCatは、ログイン機構を持たないアプリのユーザーに匿名IDを自動で振る。$RCAnonymousID: というプレフィックスにランダムな文字列が続く形式で、これが自分のCustomer profileを特定する唯一の手がかりになる^2。
問題はこのIDの長さだ。目視で書き写せる長さではないし、スクリーンショットを撮って別端末で打ち直すのも現実的ではない。アプリ内にIDを表示して、タップ一発でクリップボードにコピーできるようにしておくのが、後々いちばん効いてくる実装になる。
tanzakuでは設定画面の「アプリ情報」セクションにこの行を置いている。React Native(Expo)での実装はこんな形だ。
import { useEffect, useState } from 'react';import { Pressable, Text } from 'react-native';import * as Clipboard from 'expo-clipboard';import Purchases from 'react-native-purchases';
export function AppUserIdRow() { const [appUserID, setAppUserID] = useState<string | null>(null); const [copied, setCopied] = useState(false);
useEffect(() => { Purchases.getCustomerInfo() .then((info) => setAppUserID(info.originalAppUserId ?? null)) .catch(() => setAppUserID(null)); }, []);
const handleCopy = async () => { if (!appUserID) return; await Clipboard.setStringAsync(appUserID); setCopied(true); setTimeout(() => setCopied(false), 1500); };
return ( <Pressable onPress={handleCopy} disabled={!appUserID} hitSlop={8}> <Text>{appUserID ?? '—'}</Text> {appUserID ? ( <Text>{copied ? 'コピーしました' : 'タップでコピー'}</Text> ) : null} </Pressable> );}ポイントは3つ。
- IDは
CustomerInfoのoriginalAppUserIdから取る。SDKの初期化後ならいつでも取得できる - コピーは
expo-clipboardのsetStringAsyncを使うだけ。素のReact Nativeなら@react-native-clipboard/clipboardで同じことができる - コピーできたことが分かるフィードバック(「コピーしました」を1.5秒表示する程度)を付けておくと、押せたかどうか迷わない
この実装、開発者専用の隠し機能にする必要はない。ユーザーから不具合報告や購入トラブルの問い合わせを受けたとき、「設定画面のユーザーIDをタップしてコピーして、そのまま送ってください」と案内できる。サポート導線としてそのまま二次利用できるので、普通に見える場所に置いておくのがおすすめだ。
ステップ2 — RevenueCatのモバイルアプリで自分を探す
RevenueCatには公式のモバイルアプリがある(iOS / Android両対応)^3。ダッシュボードのフル機能があるわけではないが、顧客の検索とCustomer profileの閲覧、そしてこの記事の主役であるEntitlementsのGrantができる。
これを開発に使っている端末と同じ端末に入れておくのがポイントだ。自作アプリでIDをタップコピーし、アプリを切り替えてRevenueCatアプリの検索窓にペーストする。これで自分のCustomer profileまで、端末から一歩も出ずにたどり着ける。
PCのダッシュボードでも同じことはできるが、その場合は端末でコピーしたIDをメールなりメモ同期なりでPCへ送る一手間が挟まる。頻繁にやる操作ではないとはいえ、この一手間があるかないかで「権限の付け外し」への心理的なハードルがだいぶ変わる。
ステップ3 — Grantで付与する。Durationは短めが基本
Customer profileを開いたら、EntitlementsのカードからGrantを選ぶ。付けたいentitlement(tanzakuの場合は premium)を選択し、Durationを指定して実行すると、その場で権限が有効になる^1。アプリ側では customerInfo.entitlements.active に選んだentitlementが現れるので、通常の課金判定コードがそのまま反応する。
ここで本題のDurationだ。選択肢にはA day(1日)からLifetimeまで並んでいて、直感的には「自分は開発者なんだからLifetimeでいいだろう」と思える。が、実際に運用してみて、開発中はA dayのような短めを選ぶのが正解だと分かった。
理由は単純で、プレミアムが付いていない状態のテストが定期的に必要になるからだ。無料ユーザーにどの画面が見えるか、広告は正しく出るか、ペイウォールの導線は自然か。この確認をしたいとき、長いDurationでGrantしてあると邪魔になる。Grantした権限は途中でRevokeもできるが、ダッシュボードを開いて操作する手間を考えると、1日で勝手に切れて、必要になったらまた付けるという運用のほうがずっと楽だった。切れている時間がそのまま無料ユーザー視点のテスト時間になる。
一方で、機能開発が一段落して「プレミアム状態での普段使いテスト」がメインのフェーズに入ったら、Durationを伸ばせばいい。毎日付け直すのはさすがに面倒なので、1週間なり1ヶ月なりの中間的な長さに切り替える。さらに運用が安定して、無料状態のテストがほぼ不要になったと感じたら、そこがLifetimeに切り替える自然なタイミングだ。フェーズに応じてDurationを段階的に伸ばしていく、と捉えるのがいいと思う。
ちなみに、Grantで付与した権限はダッシュボード上で rc_promo プレフィックス付きのプロダクトとして表示されるので、本物の課金と見分けが付かなくなる心配はない^1。売上メトリクスを汚すこともない。
まとめ
RevenueCatで開発者自身にプレミアム権限を付与する手順を、実体験ベースで整理した。
- アプリ内にapp user IDのタップコピー実装を最初から仕込んでおく。開発者の権限付与にもサポート導線にも効く
- RevenueCatのモバイルアプリを開発端末に入れて、コピー→検索→Grantを端末内で完結させる
- Durationは開発中はA dayなど短めが基本。無料状態のテストがすぐできる状態を保ち、フェーズが進むにつれて段階的に伸ばす
どれも一度知ってしまえば当たり前の話だが、最初の設計時点でIDコピーの実装を入れておくかどうかで、その後の権限付け外しの気軽さがまったく変わってくる。サブスク課金をこれから入れる人は、課金コードと同じPRにAppUserIdRow相当の数行を足しておくことをおすすめしたい。
参考文献
- RevenueCat公式ドキュメント Granted Entitlements https://www.revenuecat.com/docs/dashboard-and-metrics/customer-history/promotionals
- RevenueCat公式ドキュメント Customer Profile https://www.revenuecat.com/docs/dashboard-and-metrics/customer-profile
- RevenueCat公式ブログ Introducing the Official RevenueCat iOS App https://www.revenuecat.com/blog/company/new-revenuecat-ios-ap/
- RevenueCat公式ドキュメント Entitlements https://www.revenuecat.com/docs/getting-started/entitlements