Skip to main content

Firebase

šŸ‘Pro Integration

The Firebase integration is available to all users signed up after September '23, the legacy Starter and Pro plans, and Enterprise plans. If you're on a legacy Free plan and want to access this integration, migrate to our new pricing via your billing settings.

This extension uses Firebase services as your RevenueCat backend for in-app purchases on Apple App Store, Google Play Store, and Amazon Appstore to control access to premium content and sync customer purchase information to Firestore. For example, you might want to:

  • Store purchase lifecycle events (e.g., trial starts, purchases, subscription renewals, billing issues) in Firestore and react to them.
  • Store and update information about customers and their purchases in Firestore.
  • Update information about customers' entitlements as Firebase Authentication Custom Claims.

This Firebase integration has 2 parts that can be used independently of each other: Google Analytics and Firebase Extension. The Google Analytics portion of this integration allows RevenueCat to send subscription lifecycle events to Firebase Analytics / Google Analytics. The Firebase Extension allows RevenueCat to store and update customer information in a Cloud Firestore collection and set custom claims on a user's auth token to check active entitlement status.

Each part of the integration requires additional setup, which you can see outlined in the table below.

IntegrationWhat's required
Google Analyticsāœ… $firebaseAppInstanceId customer attribute \nāŒ (optional, but highly recommended) Setting Firebase user identity
Firebase Extensionāœ… Setting Firebase user identity

Integration at a Glanceā€‹

Includes RevenueSupports Negative RevenueSends Sandbox EventsIncludes Customer AttributesSends Transfer EventsOptional Event Types
āœ…āŒāœ…āŒāœ…āŒ

1. Set up Firebase services in your projectā€‹

Before installing this extension, set up the following Firebase services in your Firebase project.

  • (optional) Cloud Firestore to store In-App Purchases & Subscriptions details.
    • Follow the steps in the documentation to create a Cloud Firestore database.
  • (optional) Firebase Authentication to enable different sign-up options for your users to enable Custom Claims management.
    • Enable the sign-in methods in the Firebase console that you want to offer your users.
āš ļøInvalid API Version

When connecting to Firebase, it's possible that you may see an error like:

"Invalid API Version", with a couple of different version numbers. This is fixed as part of an automatic upgrade process when installing the extension, and generally doesn't indicate there being an issue with your setup.

2. Set Firebase User Identity in RevenueCatā€‹

You should make sure to use the Firebase UID as the RevenueCat app user ID when setting the Firebase user identity in RevenueCat. This step is optional, but highly recommended as a best practice for the Google Analytics portion of this integration. The Firebase Extension portion requires this step to be completed.

import FirebaseAuth
import RevenueCat

func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

// Configure Purchases before Firebase
Purchases.configure(withAPIKey: "public_sdk_key")
Purchases.shared.delegate = self

// Add state change listener for Firebase Authentication
Auth.auth().addStateDidChangeListener { (auth, user) in

if let uid = user?.uid {

// identify Purchases SDK with new Firebase user
Purchases.shared.logIn(uid, { (info, created, error) in
if let error {
print("Sign in error: \(error.localizedDescription)")
} else {
print("User \(uid) signed in")
}
})
}
}
return true
}

3. Send analytics events to Google Analyticsā€‹

In order to send subscriber lifecycle events to Google Analytics, you must set the $firebaseAppInstanceId as an Attribute for your Customers and enable the integration from the RevenueCat integration settings page.

Set $firebaseAppInstanceId as a customer attributeā€‹

Please ensure you're getting the app instance ID from the Firebase Analytics package.

import FirebaseAuth
import RevenueCat

func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

// Configure Purchases before Firebase
Purchases.configure(withAPIKey: "public_sdk_key")
Purchases.shared.delegate = self

// Set the reserved $firebaseAppInstanceId attribute from Firebase Analytics
let instanceID = Analytics.appInstanceID()
if let unwrapped = instanceID {
print("Instance ID -> " + unwrapped)
print("Setting Attributes")
Purchases.shared.attribution.setFirebaseAppInstanceID(unwrapped)
} else {
print("Instance ID -> NOT FOUND!")
}

return true
}
āš ļø

Setting an incorrect app instance ID will prevent events from displaying in Google Analytics.

Enable Google Analyticsā€‹

You can "turn on" the integration from the RevenueCat dashboard.

  1. Navigate to your project in the RevenueCat dashboard and find the Integrations card in the left menu. Select + New

  1. Choose Firebase from the integrations menu

Firebase Google Analytics configuration screen

  1. Add your Firebase App ID and API secret for your iOS app and/or Android app

To set up your Firebase App ID, navigate to Google Analytics > Admin > Data Streams > iOS/Android > Add Stream. Open the App Stream to find your Firebase App ID. Copy and paste into the RevenueCat settings page.

Data stream details page

To find your API secret, in the same App stream details page select "Measure Protocol API secrets". Create an API secret. Copy and paste into the RevenueCat settings page.

Measurement Protocol API secrets page

  1. Select whether you want RevenueCat to report sales in purchased currency (original currency or in US dollar)
  2. Select whether you want sales reported as gross revenue (before app store commission), or after store commission and/or estimated taxes.

Remember to select 'Add Integration'.

Eventsā€‹

The Google Analytics portion of the Firebase integration tracks the following events:

Event TypeDefault Event NameDescriptionApp StorePlay StoreAmazonStripePromo
Initial PurchasepurchaseA new subscription has been purchased.āœ…āœ…āœ…āœ…āŒ
Trial Startedrc_trial_startThe start of an auto-renewing subscription product free trial.āœ…āœ…āœ…āœ…āŒ
Renewal (incl. trial conversion)purchaseAn existing subscription has been renewed or a lapsed user has resubscribed.āœ…āœ…āœ…āœ…āŒ
Cancellation (incl. during trial)rc_cancellationA subscription or non-renewing purchase has been cancelled. See cancellation reasons for more details.āœ…āœ…āœ…āœ…āœ…
Uncancellationrc_uncancellationA non-expired cancelled subscription has been re-enabled.āœ…āœ…āœ…āŒāŒ
Non Subscription PurchasepurchaseA customer has made a purchase that will not auto-renew.āœ…āœ…āœ…āœ…āœ…
Subscription Pausedrc_subscription_pausedA subscription has been paused.āŒāœ…āŒāŒāŒ
Expirationrc_expirationA subscription has expired and access should be removed. If you have Platform Server Notifications configured, this event will occur as soon as we are notified (within seconds to minutes) of the expiration. If you do not have notifications configured, delays may be approximately 1 hour.āœ…āœ…āœ…āœ…āœ…
Billing Issuerc_billing_issueThere has been a problem trying to charge the subscriber. This does not mean the subscription has expired. Can be safely ignored if listening to CANCELLATION event + cancel_reason=BILLING_ERROR.āœ…āœ…āœ…āœ…āŒ
Product Changerc_product_changeA subscriber has changed the product of their subscription. This does not mean the new subscription is in effect immediately. See Managing Subscriptions for more details on updates, downgrades, and crossgrades.āœ…āœ…āŒāœ…āŒ
Transferrc_transfer_eventA transfer of transactions and entitlements was initiated between one App User ID(s) to another. Please note: Two events will be sent for each transfer, one for the original user and another for the destination user.āœ…āœ…āœ…āœ…āŒ

Testing Google Analyticsā€‹

Make a sandbox purchase with a new userā€‹

Simulate a new user installing your app, and go through your app flow to complete the sandbox purchase.

Check Google Analytics Dashboardā€‹

Navigate to Google Analytics > Reports > Realtime. Here you will be able to confirm events have been successfully dispatched to Google Analytics. It can take up to a few seconds or minutes for your events to appear.

Google Analytics dashboard

Firebase A/B Testingā€‹

While these events will appear in Firebase, Google does not allow events that are submitted via the Google Analytics 4 Measurement Protocol API to be used with Firebase A/B testing at this time. Since the integration uses this API, these events are not yet compatible with Firebase A/B Testing.

šŸ‘

You have completed the Google Analytics setup! You can stop here or continue with the rest of the documentation to learn how to set up the Firebase Extension.

4. Send customer information to Firestoreā€‹

Prerequisitesā€‹

This section outlines steps that need to be completed in order to enable the Firebase Extension portion of this integration.

Billingā€‹

Your Firebase project must be on the Blaze (pay-as-you-go) plan to install an extension.

You will be charged a small amount (typically around $0.01/month) for the Firebase resources required by this extension (even if it is not used). In addition, this extension uses the following Firebase services, which may have associated charges if you exceed the service's free tier for low-volume use (Learn more about Firebase billing):

  • Cloud Firestore
  • Cloud Functions

Set your Cloud Firestore security rulesā€‹

Set your security rules so that only authenticated users can access customer information, and that each user can only access their own information.

rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /${param:REVENUECAT_CUSTOMERS_COLLECTION}/{uid} {
allow read: if request.auth.uid == uid;
}

match /${param:REVENUECAT_EVENTS_COLLECTION}/{id} {
allow read: if request.auth.uid == resource.app_user_id
}
}
}

Enable Firebase Extensionā€‹

You can install this extension either through the Firebase Console or CLI on your OS.

Install Firebase Extension through Firebase Consoleā€‹

Follow this installation link to start the installation prompts on Firebase Console.

  1. Select 'I acknowledge'

  1. If your account is not set up for billing yet, select 'Upgrade project to continue'

  1. Enable Authentication and Secret Manager by selecting 'Enable', then select 'Next'

  1. Select 'Next'

  1. Configure the extension

  • Select a Cloud Functions location
  • (optional) Give a name to the Firestore collection where "events" will be stored
  • (optional) Give a name to the Firestore collection where "customers" will be stored
  • Enable or disable custom claims set in Firebase Auth with user's active entitlements. If set to ā€œENABLEDā€, the extension will consider the app_user_id of the user to match the userā€™s Firebase Authentication UID and set a ā€œCustom Claimā€ with their current active entitlements
  • Enter your RevenueCat Firebase Integration Shared Secret. This can be found in the RevenueCat Firebase Extension settings page. Select 'Generate shared secret' and copy it. Paste the generated shared secret in the installation prompt.

  • (optional) Enable events to write custom event handlers via Eventarc

Available Events:ā€‹
EventDescription
testOccurs whenever a test event issued through the RevenueCat dashboard.
initial_purchaseOccurs whenever a new subscription has been purchased or a lapsed user has resubscribed.
non_renewing_puchaseOccurs whenever a customer has made a purchase that will not auto-renew.
renewal Occurs whenever an existing subscription has been renewed.
product_changeOccurs whenever a subscriber has changed the product of their subscription.
cancellationOccurs whenever a subscription or non-renewing purchase has been cancelled. See cancellation reasons for more details.
uncancellation Occurs whenever an auto-renew status has been re-enabled for a subscription.
billing_issueOccurs whenever there has been a problem trying to charge the subscriber. This does not mean the subscription has expired.
subscriber_aliasDeprecated. Occurs whenever a new app_user_id has been registered for an existing subscriber.
subscription_pausedOccurs whenever a subscription has been paused.
transfer Occurs whenever a transfer of transactions and entitlements was initiated between one App User ID(s) to another.
expiration Occurs whenever a subscription has expired and access should be removed.
  • Select 'Install extension'. This will take about 3-5 minutes to complete
  1. Once the extension is installed, navigate to Firebase > Functions in the sidebar. Copy the 'Trigger URL' and paste this into the RevenueCat Firebase Extension settings page.

Remember to select 'Save'

šŸ‘

You have successfully installed your instance of Enable In-App Purchases with RevenueCat! Skip to Testing Firebase Extension section of the docs.

Install Firebase Extension through CLIā€‹

If you installed the Firebase Extension through the Firebase Console, skip to Testing Firebase Extension of the docs.

This portion of the installation is done through the command-line interface (CLI). Clone this Github repo and open the CLI for your respective operating system.

  1. Run firebase ext:install . --project [project-id]
    To find your project-id, go to your Firebase console. Select your project and navigate to Project settings to copy the ID and replace [project-id] in the command.

  1. For the next 2 Do you wish to continue? prompts, press y

  1. Please enter a new name for this instance: Give the extension a name of your choice

  1. Which option do you want enabled for this parameter (Cloud Functions location)? Select your desired location

  1. Enter a value for RevenueCat Webhook Events Firestore collection: Give a name to the Firestore collection where "events" will be stored. If left blank, RevenueCat will not save events.

  1. Enter a value for location of the customers collection: Give a name to the Firestore collection where the customer information will be stored. If left blank, RevenueCat will not save customer information.

  1. Which option do you want enabled for this parameter (custom claims set in Firebase Auth with the user's active entitlements): If you want to use the custom claims feature, which allows for automatic checking for Entitlements, select ENABLED.

  1. Enter a value for RevenueCat Firebase Integration Shared Secret: This can be found in the RevenueCat Firebase Extension settings page. Select 'Generate shared secret' and copy it. Paste the generated shared secret in the installation prompt.

RevenueCat Firebase Extension page

  1. Wait about 3 to 5 minutes for the installation

  1. Once the extension is installed, navigate to Firebase > Functions in the sidebar. Copy the 'Trigger URL' and paste this into the RevenueCat Firebase Extension settings page.

Note about the App User ID's in the Customers collectionā€‹

The document ID's in the Customers collection will always be an App User ID. Specifically, it will be the customer's most recently active alias. This means that the document ID for each customer may switch between anonymous ID's and custom ID's, if they are both used in your app. If you would like to only use custom ID's, you can learn more about that here.

Remember to select 'Save'.

šŸ‘

You have successfully installed your instance of Enable In-App Purchases with RevenueCat!

Testing Firebase Extensionā€‹

Make a sandbox purchase with a new userā€‹

Simulate a new user installing your app, and go through your app flow to complete the sandbox purchase.

Check that the Firebase event delivered successfullyā€‹

While still on the Customer View, select the purchase event in the Customer History page and make sure that the Firebase (Firebase function) integration event exists and was delivered successfully.

Check Firestore Database Collectionsā€‹

Navigate to your Firebase dashboard > Firestore Database to find events sent for your collections.

Customers collection

Events collection

Sample Eventsā€‹

Below are sample JSONs that are delivered to Firestore Database for each event type.

{
"app_instance_id": "1234567ab8901cd234e56f789gh0i123",
"user_id": "1234567890",
"events": [
{
"name": "purchase",
"params": {
"event_id": "12345678-1234-56a7-b8c9-012defg3h4i5",
"product_id": "com.tokens.1000",
"period_type": "NORMAL",
"purchased_at": 1658338961415000,
"environment": "PRODUCTION",
"presented_offering_id": "",
"transaction_id": "GPA.1234-5678-9012-34567",
"affiliation": "PLAY_STORE",
"original_transaction_id": "GPA.1234-5678-9012-34567",
"original_app_user_id": "$RCAnonymousID:87c6049c58069238dce29853916d624c",
"currency": "USD",
"value": 1.99,
"coupon": "",
"is_trial_conversion": false,
"is_renewal": false,
"items": [
{
"item_id": "com.tokens.1000",
"affiliation": "PLAY_STORE"
}
]
}
}
]
}
{
"app_instance_id": "1234567ab8901cd234e56f789gh0i123",
"user_id": "1234567890",
"events": [
{
"name": "rc_uncancellation",
"params": {
"event_id": "12345678-1234-56a7-b8c9-012defg3h4i5",
"product_id": "yearly_sub",
"period_type": "TRIAL",
"purchased_at": 1653559391000000,
"environment": "PRODUCTION",
"presented_offering_id": null,
"transaction_id": "123456789012345",
"affiliation": "APP_STORE",
"original_transaction_id": "123456789012345",
"original_app_user_id": "$RCAnonymousID:87c6049c58069238dce29853916d624c",
"expiration_at": 1653818591000000
}
}
]
}

Using the Extensionā€‹

Checking Entitlement accessā€‹

To check access to entitlements, you can either use the RevenueCat SDK or use Firebase Authentication custom claims. For example, to check whether the current user has access to an entitlement called premium, you could use the following Firebase code:

getAuth().currentUser.getIdTokenResult()
.then((idTokenResult) => {
// Confirm the user has a premium entitlement.
if (!!idTokenResult.claims.revenueCatEntitlements.includes("premium")) {
// Show premium UI.
showPremiumUI();
} else {
// Show regular user UI.
showFreeUI();
}
})
.catch((error) => {
console.log(error);
});

List a user's active subscriptionsā€‹

To list a user's active subscriptions, you could use the following Firebase code:

getDoc(doc(db, "${param:REVENUECAT_CUSTOMERS_COLLECTION}", getAuth().currentUser.uid))
.then((snapshot) => {
if (snapshot.exists()) {
snapshot.subscriptions
.filter(subscription => new Date(subscription.expires_date) >= new Date())
.forEach(subscription => console.log(JSON.stringify(subscription)));
}
});

React to subscription lifecycle eventsā€‹

Subscription lifecycle events get stored as events in the Firestore collection ${param:REVENUECAT_EVENTS_COLLECTION}. By listening to changes in this collection, for example, through Cloud Firestore triggered Firebase Cloud Functions, you can trigger any custom behavior that you want. An example could be sending push notifications to customers with billing issues to prompt them to update their credit cards. To do that, you would:

  • Store a push notification token for each of your app users, e.g., using Firebase Cloud Messaging
  • Create a new Cloud Function triggered whenever a new document is created in the ${param:REVENUECAT_EVENTS_COLLECTION} collection
  • In the Cloud Function, determine if the type field of the new document is "BILLING_ISSUE"
  • If so, look up the app user ID from the app_user_id field of the new document
  • Look up the push token for that app user ID and send a push notification

Troubleshooting your Firebase integrationā€‹

403 Permission denied to enable service (eventarcpublishing.googleapis.com)ā€‹

If you get a 403 error in DeploymentManager when trying to install or uninstall the Firebase extensions, Navigate to Google Cloud IAM Settings and follow these steps:

  1. Near the top left corner of the page, click Grant Access.
  2. Once the "Grant Access" popup shows up on the right side of the page, set <PROJECT_NUMBER>@cloudservices.gserviceaccount.com as the principal (replacing <PROJECT_NUMBER> with your actual project number.)
  3. Select the Editor role.
  4. Click Save.

Now try uninstalling and/or reinstalling the extension.

InvalidApiVersionError: The version of this extension is not the same.ā€‹

This is fixed as part of an automatic upgrade process when installing the extension, and generally doesn't indicate there being an issue with your setup. The error should not affect your integration. This is usually not necessary but if you continue seeing this error you may try to uninstall and reinstall the extension.