从 Web 应用发起购买
在应用内,“升级”按钮会导航到 revenuecat://purchase?external_id=SUPABASE_USER_ID&product=PRODUCT_ID。正是把 Supabase 用户 ID 作为 external_id 传入,webhook 才能把这笔购买对应回数据库中的某一行。
Claude Code
Claude Code 和 Supabase 是天生一对:代理编写数据库结构、策略和边缘函数,Supabase 负责运行它们。在 WebViewGold 应用中,有五件事需要特别注意,而浏览器从来不会对您提出这些要求:WebView 中的身份验证、魔法链接、账户删除、推送用户 ID 和商店内购买。下面是配置清单。
每个平台一次性 $109 起,或由我们的团队全程代劳,$698 起。
邮箱和密码登录无需任何改动:会话保存在 WebView 的存储中,只要封装层不清除它,就会一直保留(Config.swift 中的 deletecache 和 Config.java 中的 CLEAR_CACHE_ON_STARTUP 保持为 false)。OAuth 则不同。Google 拒绝在嵌入式 WebView 中完成登录(disallowed_useragent 错误),因此 WebViewGold 提供了 Social Login Helper:您列出登录提供方流程的 URL 前缀,封装层就会在一个提供方认可的专用登录窗口中打开这部分流程,完成后再返回您的应用。对于使用 Google 登录的 Supabase,触发规则是 https://accounts.google.com,在 google_login_helper_triggers(Config.swift)和 GOOGLE_LOGIN_HELPER_TRIGGERS(Config.java)中设置。Sign in with Apple 无需任何配置:封装层会自动识别 appleid.apple.com。
也就是说:在 Supabase 后台中启用 Apple 提供方(Services ID、密钥、Team ID、回调 URL),在 Google 按钮旁添加 Apple 按钮,以满足准则 4.8,并让 Claude Code 为两者接入 signInWithOAuth,重定向地址指向您的生产域名。
邮件中的魔法链接默认会在浏览器中打开。Universal Links 和 App Links 则会把它送进应用。
让 Claude Code 在 Web 项目中添加 /.well-known/apple-app-site-association(包含您的 Team ID 和 Bundle ID 的 JSON,不带文件扩展名,并以 JSON 内容类型提供)和 /.well-known/assetlinks.json(您的包名和签名证书指纹)。在 Next.js 中,就是 public 文件夹加一条响应头规则。
iOS:在 Xcode 中添加 Associated Domains,值为 applinks:app.example.com,并在 Config.swift 中把 ShowExternalLink 设为 true。Android:在 AndroidManifest.xml 中为您的域名添加 intent filter,并在 Config.java 中把 IS_DEEP_LINKING_ENABLED 设为 true。详情见Universal Links 文档和App Links 文档。
把站点 URL 和重定向白名单设为 https://app.example.com/auth/callback。这样邮件中的链接就会落在您的域名上,而只要应用已安装,系统就会把它交给应用。
有些邮件应用会在自己的浏览器中打开链接。让 Claude Code 添加一个六位数 OTP 选项(在 Supabase 后台的魔法链接邮件模板中加入 token 变量),这样即使用户最终进入了 Safari,也仍然可以在应用内完成登录。如果您使用 PKCE 流程,这个备用方案就更加重要,因为 code verifier 只存在于发起登录的那个上下文中。
Apple 5.1.1 和 Google Play 要求支持应用内删除;在 Supabase 中只需一个函数就能做到,service role 密钥始终保留在服务器端。
按照 Apple 和 Google Play 的要求,为这个 Supabase 应用实现账户删除。 1. 创建一个 Supabase 边缘函数 delete-account:从 Authorization 请求头读取用户 JWT,并用 anon 客户端验证;然后使用只在函数内部创建的 service-role 客户端,删除该用户在所有引用 auth.users 的表中的数据行(从数据库结构中列出这些表;缺少 ON DELETE CASCADE 外键的地方优先补上,并编写迁移),删除该用户在存储桶中的文件,最后调用 auth.admin.deleteUser(userId)。成功时返回 204,否则返回清晰的错误信息。 2. 在 Web 应用中添加“设置 - 删除账户”,带确认对话框,说明会删除哪些内容;用当前会话调用该函数,退出登录并显示确认页面。如果存在 RevenueCat 订阅,提示用户先在 App Store 或 Google Play 设置中取消订阅。 3. 添加一个公开的 /delete-account 页面,为没有安装应用的用户说明删除流程。 4. 在 /privacy 中加一句关于账户删除的说明。 5. 编写一个测试:创建一个临时用户,插入数据行,调用该函数,并断言所有数据都已删除。

出色的工作!无需任何编码就能轻松完成。简单快捷!创作者也提供了大力帮助!
anon 密钥本来就设计为放在客户端代码中,而已发布的应用任何人都可以下载。让这一切保持安全的,是行级安全(Row Level Security)。
把 autoInjectVariable / AUTO_INJECT_VARIABLES 设为 true 后,封装层会在每个页面上注入 onesignalplayerid;否则就用 getonesignalplayerid:// 来请求它。把它保存到用户资料中,这样边缘函数就能定向推送给单个用户。
// after login, inside the native app only
import { supabase } from "./supabase";
import { isNativeApp, readInjected, callNative } from "./native";
export async function syncPushSubscription(userId) {
if (!isNativeApp()) return;
let playerId = window.onesignalplayerid; // present when auto-inject is on
if (!playerId) {
callNative("getonesignalplayerid://");
playerId = await readInjected("onesignalplayerid", 3000).catch(function () { return null; });
}
if (!playerId) return;
await supabase.from("profiles").update({ onesignal_player_id: playerId }).eq("id", userId);
}
// RLS policy to pair with it (SQL):
// create policy "users update own profile" on profiles for update
// using (auth.uid() = id) with check (auth.uid() = id);在应用内,“升级”按钮会导航到 revenuecat://purchase?external_id=SUPABASE_USER_ID&product=PRODUCT_ID。正是把 Supabase 用户 ID 作为 external_id 传入,webhook 才能把这笔购买对应回数据库中的某一行。
提示词:“创建一个边缘函数 revenuecat-webhook,验证在 RevenueCat 中配置的 Authorization 请求头,把事件以 app_user_id 为键 upsert 到 subscriptions 表中,并根据事件类型设置 is_active 标志。”客户端通过 RLS 读取权益,绝不依赖客户端的购买结果。
浏览器中可以继续使用 Stripe。使用同一套权益模型(一张带有 source 列的 subscriptions 表),这样无论用户在哪里付款,功能都会以同样的方式解锁。请参阅RevenueCat 设置指南。
Apple 小型企业计划和 Google 的 15% 费率档:每年收入 100 万美元以下的部分佣金为 15%,超出部分为 30%。在两个控制台中申请,并告知 RevenueCat。
不需要。在 WebViewGold 中运行的就是使用 supabase-js 的 Web 应用。原生层只通过 URL scheme 添加推送、生物识别、购买和深度链接。
会,只要封装层不在启动时清除存储。把 deletecache(iOS)和 CLEAR_CACHE_ON_STARTUP(Android)保持为 false,并在 Supabase 后台中设置合理的会话有效期。
Google 会阻止嵌入式 WebView。在两个 WebViewGold 配置中为 accounts.google.com 设置 Social Login Helper 触发规则;封装层随后会在一个被认可的窗口中完成登录,然后返回您的应用。
只要您提供数据库结构,并用通俗的语言描述访问规则,它就能写出不错的初稿。审阅每一条策略,用两个不同的用户测试,并且绝不要因为演示能跑通就发布一张没有 RLS 的表。
服务器。RevenueCat webhook 调用边缘函数,这才是可信的数据来源;客户端只读取由此产生的数据行。在任何可下载的应用中,客户端的标志都可能被伪造。
结果相同,只是您需要投入的工作量不同。三种方式都附带审核通过保证和 7×24 小时人工支持。
$109 每个平台,一次性付费
WebViewGold 许可证:一个现成的 Xcode 或 Android Studio 项目。粘贴您的 URL,设置名称和图标,开启所需功能,构建并提交。永久免费更新。
在主页查看方案$349 每个许可证,一次性附加购买
无需 Mac、Xcode 或 Android Studio:在浏览器中完成配置,我们在云端构建两个应用,并将其交付到 App Store Connect 和 Play Console。
Cloud Builder 如何运作 试用免费演示$698 每个平台 $798
把您的 URL 和图标发给我们。我们的团队在 72 小时内完成配置、构建并交付您的应用,白标,附源码项目。两个平台共 $1,158。
Full Service 详情 服务提供方:冬季特惠价格有效期至 2026年12月31日。
App Store & Google Play 审核通过保证 – 否则 14 天内退款
想直接交给我们?Full Service:我们在 72 小时内完成配置、构建并交付,每个平台 $698 起。有疑问?通过 7×24 小时在线聊天联系我们。
退款依据我们 FAQ 中列出的条件:应用因非内容原因被 Apple 和/或 Google 拒审,并在购买后 14 天内提出申请。