Documentation

Firebase rules

Only needed when premium data lives in Firestore. Firestore rules cannot ask RevenueCat who paid, so you mirror paid status into Firestore first.

Do you actually need this?

Most apps can skip this page entirely. If your premium feature is a client-side unlock — hiding buttons, exports, themes, local limits — usePremium() already does the job and you are done.

You only need rules when paid users read or write Firestore documents that free users must never touch. Then the database itself has to enforce who paid, not just your UI.

The key limitation

Firestore security rules cannot call RevenueCat (or any external API). Rules can only look at the incoming request and at documents already in Firestore. So you copy — “mirror” — the paid status into a Firestore document, and the rules read that.

1

The full flow in plain English

  1. 1. User buys in the app. RevenueCat activates the pro entitlement, same as always.
  2. 2. RevenueCat calls your server. A webhook fires on every purchase, renewal, and cancellation.
  3. 3. Your server writes one Firestore document. The webhook handler marks that user’s entitlement document as active (or inactive).
  4. 4. Firestore rules check that document. Premium reads are allowed only when the document says active: true.

Good to know

One prerequisite: this only works with an auth adapter connected (see the previous page). The user id in Firestore must match the user id you send to RevenueCat — otherwise the webhook cannot find the right document to update.
2

Store one entitlement document per user

The webhook maintains a single small document per user. Rules read it whenever they need to decide if premium data should be available.

text

1users/{uid}/entitlements/pro2{3  active: true,4  source: "revenuecat",5  updatedAt: <server timestamp>,6  expiresAt: <timestamp, optional>7}

The uid must be the same app user id your auth adapter gives RevenueCat. Same id on both sides, or the mirror breaks.

3

Add the Firestore rules

Copy these into your firestore.rules file. They do three things: let users read their own entitlement, block anyone from faking one, and protect premium content behind a paid check.

firestore.rules

1rules_version = '2';2service cloud.firestore {3  match /databases/{db}/documents {4 5    function isPro(uid) {6      return get(/databases/$(db)/documents/users/$(uid)/entitlements/pro)7        .data.active == true;8    }9 10    // Users own their basic document11    match /users/{uid} {12      allow read, write: if request.auth.uid == uid;13 14      // Entitlements are written only by the webhook (Admin SDK)15      match /entitlements/{name} {16        allow read: if request.auth.uid == uid;17        allow write: if false;18      }19    }20 21    // Premium-only collection22    match /premiumContent/{doc} {23      allow read: if request.auth != null && isPro(request.auth.uid);24      allow write: if false;25    }26  }27}

Tip

Why “allow write: if false” is safe: the webhook writes with the Firebase Admin SDK from your server, which bypasses security rules entirely. Blocking client writes means no app user can ever grant themselves premium.
4

Keep the mirror updated with a webhook

A RevenueCat webhook keeps the mirror honest — when a subscription renews, lapses, or is refunded, Firestore reflects it within seconds. The kit includes a Next.js route example that verifies a shared secret, reads app_user_id, and updates the document:

text

1POST /api/revenuecat-webhook2Authorization: Bearer ${REVENUECAT_WEBHOOK_SECRET}3 4event.app_user_id  ->  users/{uid}/entitlements/pro { active, expiresAt }

Watch out

Server only. The webhook secret and Firebase Admin credentials live in server environment variables. Never write entitlement documents from the mobile app, and never ship Admin keys in it.
5

How to know it worked

Run through this with a sandbox purchase

  • A sandbox purchase creates or updates users/{uid}/entitlements/pro.
  • The entitlement document shows active: true for the paid user.
  • A free logged-in user cannot read premium-only Firestore documents.
  • A paid logged-in user can read premium-only Firestore documents.
  • Client code cannot write or fake its own entitlement document.
  • Cancelling the sandbox subscription flips the document back to inactive.