Skip to content
WebViewGold Vibe Coding to App Store
English
Get WebViewGold

Backend checklists

Supabase app to the App Store and Google Play: the complete checklist

Lovable, Bolt, Tempo, Hostinger Horizons and most Cursor projects ship with Supabase underneath. Supabase runs perfectly inside a WebViewGold app, but a handful of settings quietly assume a browser tab. This checklist walks through each of them in the order you will meet them.

From $109 one-time per platform, or let our team do it all from $698.

  • Approval guarantee – or money back within 14 days
  • No coding needed
  • One-time payment, free updates
  • 24/7 human support
  • Made in Germany since 2014 · ISO 27001

1. Auth configuration: Site URL and redirect URLs

Supabase dashboard → Authentication → URL Configuration. These values decide where every email link and OAuth callback lands.

  • Site URL = your production domain (https://app.yourbrand.com), never the lovable.app preview or localhost. The custom domain guide explains why the app must load a domain you own.
  • Redirect URLs: add every callback path you use (https://app.yourbrand.com/auth/callback, /reset-password, /**). Remove tunnel and preview URLs before launch.
  • Email templates use {{ .SiteURL }} and {{ .RedirectTo }}; check that confirmation, magic link and recovery mails point at your domain.
  • Sessions persist like in a browser as long as the cache-clearing options stay off in WebViewGold (deletecache in Config.swift, CLEAR_CACHE_ON_STARTUP in Config.java).

2. Social login: Google and Apple

Guideline 4.8 says: if you offer Google login, you must also offer Sign in with Apple (or an equivalent privacy-focused option).

  1. Google: keep the Supabase provider, add the WebViewGold helper

    Google refuses OAuth inside embedded WebViews (the "disallowed_useragent" error). WebViewGold's Social Login Helper fixes it without code changes: set google_login_helper_triggers in Config.swift to ["https://accounts.google.com", "https://accounts.youtube.com"] and GOOGLE_LOGIN_HELPER_TRIGGERS in Config.java; the login then runs in a dedicated window with an accepted user agent. Details in the disallowed_useragent guide.

  2. Apple: enable the provider in Supabase

    Apple Developer: App ID with the Sign in with Apple capability, a Services ID whose return URL is https://YOUR-PROJECT.supabase.co/auth/v1/callback (or your custom auth domain), and a .p8 key. Supabase: Authentication → Providers → Apple with Services ID, Team ID, Key ID and the generated client secret. The secret is a JWT that expires after at most six months; put a reminder in your calendar.

  3. Add the button in the web app

    supabase.auth.signInWithOAuth({ provider: "apple", options: { redirectTo: "https://app.yourbrand.com/auth/callback" } }). Show the Apple button at least as prominently as Google. WebViewGold detects appleid.apple.com automatically; no helper configuration needed.

  4. Test both on a real iPhone

    Complete Google and Apple sign-in in the TestFlight build, including a brand-new account with an Apple "Hide my email" relay address.

3. Magic links and password resets through Universal Links

A magic link opened from Mail lands in Safari by default: the user is logged in on the website but not in the app. Universal Links (iOS) and App Links (Android) route links to your domain into the app instead. Host /.well-known/apple-app-site-association and /.well-known/assetlinks.json in your project's public folder, add the Associated Domains capability (applinks:app.yourbrand.com) and set ShowExternalLink to true in Config.swift; on Android enable IS_DEEP_LINKING_ENABLED in Config.java and add the domain to the intent filter in AndroidManifest.xml. The Universal Links docs and the App Links docs have the exact steps.

On the Supabase side, use the PKCE flow (default in supabase-js v2) and call exchangeCodeForSession on your callback page. Disable click tracking for auth emails, because a tracking domain in the link defeats the association. The deep links guide covers testing.

Great way of converting your web app to a native app! Fast turn-around, and a great way to get your apps into the app stores without the need to develop a full native app!

Kevin Joling · FlightConnections & TrainConnections · Trustpilot

4. Account deletion edge function

Apple Guideline 5.1.1(v) and Google's account deletion policy require an in-app way to delete the account and its data. The client cannot delete an auth user; a small edge function with the service role key can. Wire a "Delete account" button to it, sign the user out afterwards, and add a public /delete-account page (Google asks for that URL). Full flow: the account deletion guide.

typescript
// supabase/functions/delete-account/index.ts
import { createClient } from "npm:@supabase/supabase-js@2";

Deno.serve(async (req) => {
  const authHeader = req.headers.get("Authorization") ?? "";
  const userClient = createClient(Deno.env.get("SUPABASE_URL")!, Deno.env.get("SUPABASE_ANON_KEY")!, {
    global: { headers: { Authorization: authHeader } },
  });
  const { data: { user }, error } = await userClient.auth.getUser();
  if (error || !user) return new Response("Unauthorized", { status: 401 });

  const admin = createClient(Deno.env.get("SUPABASE_URL")!, Deno.env.get("SUPABASE_SERVICE_ROLE_KEY")!);
  await admin.from("profiles").delete().eq("id", user.id); // or use ON DELETE CASCADE to auth.users
  const { error: delError } = await admin.auth.admin.deleteUser(user.id);
  if (delError) return new Response(delError.message, { status: 500 });
  return new Response(JSON.stringify({ ok: true }), { headers: { "Content-Type": "application/json" } });
});

5. Data: RLS, storage uploads and privacy

  • Row Level Security on every table with user data. Builders sometimes generate "allow all" policies to get a demo working; audit them under Table editor → Policies before launch.
  • Storage: private buckets with signed URLs for user files; public buckets only for truly public assets.
  • Uploads from the WebView just work: a standard file input (accept="image/*") opens the native photo picker or camera. Write real permission texts for camera and photo library in Info.plist and delete the permissions you do not use.
  • The anon key in the client is fine by design; the service role key belongs only in edge functions and server code.
  • App Privacy (Apple) and Data safety (Google): a Supabase app collects at least email, user ID and user content; list Supabase as a processor in your privacy policy. The privacy guide has the typical answers.

6. Push user IDs and the RevenueCat webhook

Two backend touchpoints that make the native features personal.

  1. Store the push subscription ID per user

    After login, navigate to getonesignalplayerid://; WebViewGold sets window.onesignalplayerid (or enable autoInjectVariable / AUTO_INJECT_VARIABLES to get it without the call). Upsert it into profiles.push_id and send targeted notifications from an edge function through the OneSignal REST API. Firebase and Pushwoosh work the same way.

  2. Receive RevenueCat events

    Create an edge function as the webhook endpoint, verify the Authorization header you set in RevenueCat, and write subscriptions(user_id, entitlement, expires_at, store). Because your web app triggers purchases with revenuecat://purchase?external_id=USER_ID&product=PRODUCT, the webhook's app_user_id is exactly your Supabase user ID.

  3. Gate features server-side

    Premium checks read the subscriptions table through RLS, never a flag in localStorage. Stripe webhooks from the web version write the same table, so one check covers both channels (RevenueCat guide).

Frequently asked questions

Do I need a native Supabase SDK or a different auth flow for the app?

No. The web SDK you already use runs inside the WebView. The only additions are WebViewGold's Social Login Helper for Google and the Universal Links setup for email links.

Do Supabase Realtime and websockets work inside WebViewGold?

Yes. WKWebView and the Android WebView support websockets, so Realtime subscriptions behave as in the browser.

Will users stay logged in between app launches?

Yes, as long as the cache-clearing options in the Config files stay off. The session is refreshed by supabase-js exactly as on the web.

Do magic links work without Universal Links?

They log the user in, but in Safari rather than in the app. For a login-centric app that is confusing enough to be worth the one-hour setup.

Three ways to get your app into the stores

Same result, different amount of work on your side. All three come with the approval guarantee and 24/7 human support.

Do it yourself

$109 per platform, one-time

The WebViewGold license: a finished Xcode or Android Studio project. Paste your URL, set name and icon, switch on features, build and submit. Free updates forever.

See plans on the main page

Cloud Builder

$349 per license, one-time add-on

No Mac, no Xcode, no Android Studio: configure in the browser, we build both apps in the cloud and hand them to App Store Connect and the Play Console.

How the Cloud Builder works Try the free demo

Full Service

$698 per platform $798

Send us your URL and icon. Our team configures, builds and delivers your app within 72 hours, white-label, with source projects. Both platforms for $1,158.

Full Service details Powered by WeSetupYourWebViewApp

Winter Sale prices valid until December 31, 2026.

Ready to ship your app?

App Store & Google Play approval guarantee – or your money back within 14 days

Rather hand it over? Full Service: we configure, build and deliver within 72 hours, from $698 per platform. Questions? Chat with us 24/7.

Refunds are granted under the conditions listed in our FAQ: a non-content rejection by Apple and/or Google, claimed within 14 days after purchase.