Firebase

Integrate in-app purchase events from RevenueCat with Firebase

πŸ‘

The Firebase integration is available on the Starter plan.

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.

Integration

What's required

Google Analytics

βœ… $firebaseAppInstanceId subscriber attribute
❌ (optional, but highly recommended) Setting Firebase user identity

Firebase Extension

βœ… Setting Firebase user identity

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 e = error {
                    print("Sign in error: \(e.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 a subscriber attribute for your users and enable the integration from the RevenueCat integration settings page.

Set $firebaseAppInstanceId as a subscriber 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 subscriber 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
332332
  1. Choose Firebase from the integrations menu
932932

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.

25572557

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.

18061806

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 Type

Event Name

Description

Initial Purchase

purchase

The first purchase of an auto-renewing subscription product that does not contain a free trial.

Renewal (incl. trial conversion)

purchase

When an auto-renewing subscription product renews OR a user repurchases the auto-renewing subscription product after a lapse in their subscription.

Trial Started

rc_trial_start

The start of an auto-renewing subscription product free trial.

Cancellation (incl. during trial)

rc_cancellation

When a user turns off renewals for an auto-renewing subscription product.

Uncancellation

rc_uncancellation

When a user re-enables the auto-renew status for a subscription.

Non Subscription Purchase

purchase

The purchase of any product that's not an auto-renewing subscription.

Billing Issue

rc_billing_issue

When a billing issue is detected.

Subscription Paused

rc_subscription_paused

When a subscription is paused. Available for Google Play subscriptions only.

Transfer

rc_transfer

A transfer of transactions and entitlements was initiated between one App User ID(s) to another.

Expiration

rc_expiration

When a subscription expires.

Product Change

rc_product_change

When user 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.

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.

10711071

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 roles 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'
17341734
  1. If your account is not set up for billing yet, select 'Upgrade project to continue'
16561656
  1. Enable Authentication and Secret Manager by selecting 'Enable', then select 'Next'
15441544
  1. Select 'Next'
15881588
  1. Configure the extension
15361536
  • 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.
934934
  • (optional) Enable events to write custom event handlers via Eventarc
14781478

Available Events:

Event

Description

test

Occurs whenever a test event issued through the RevenueCat dashboard.

initial_purchase

Occurs whenever a new subscription has been purchased.

non_renewing_puchase

Occurs whenever a customer has made a purchase that will not auto-renew.

renewal

Occurs whenever an existing subscription has been renewed. This may occur at the end of the current billing period or later if a lapsed user re-subscribes.

product_change

Occurs whenever a subscriber has changed the product of their subscription.

cancellation

Occurs 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_issue

Occurs whenever there has been a problem trying to charge the subscriber. This does not mean the subscription has expired.

subscriber_alias

Deprecated. Occurs whenever a new app_user_id has been registered for an existing subscriber.

subscription_paused

Occurs 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.
25492549 932932

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.
13111311 20682068 25332533
  1. For the next 2 Do you wish to continue? prompts, press y
10461046
  1. Please enter a new name for this instance: Give the extension a name of your choice
17501750
  1. Which option do you want enabled for this parameter (Cloud Functions location)? Select your desired location
15351535
  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.
17131713
  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.
24802480
  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.
24762476
  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.
18581858

RevenueCat Firebase Extension page

19721972
  1. Wait about 3 to 5 minutes for the installation
22492249
  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.
25492549 932932

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.

28022802

Check Firestore Database Collections

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

25612561

Customers collection

25632563

Events collection

Sample Event

Below is a sample JSON that is delivered to Firestore Database for a renewal event.

{
  "request_body": "{\"event\": {\"event_timestamp_ms\": 1650416910722, \"product_id\": \"monthly_pro\", \"period_type\": \"NORMAL\", \"purchased_at_ms\": 1650416898000, \"expiration_at_ms\": 1650417198000, \"environment\": \"SANDBOX\", \"entitlement_id\": null, \"entitlement_ids\": [\"pro\"], \"presented_offering_id\": \"default\", \"transaction_id\": \"2000000036373963\", \"original_transaction_id\": \"1000000976812525\", \"is_family_share\": false, \"country_code\": \"US\", \"app_user_id\": \"21kYSQxa0Ga61JqXtup1T2tibAe2\", \"aliases\": [\"$RCAnonymousID:7fd423d73f8240edbc186360f14a3f97\", \"21kYSQxa0Ga61JqXtup1T2tibAe2\"], \"original_app_user_id\": \"$RCAnonymousID:7fd423d73f8240edbc186360f14a3f97\", \"currency\": \"USD\", \"is_trial_conversion\": false, \"price\": 2.49, \"price_in_purchased_currency\": 2.49, \"subscriber_attributes\": {\"$attConsentStatus\": {\"value\": \"notDetermined\", \"updated_at_ms\": 1650416909148}}, \"store\": \"APP_STORE\", \"takehome_percentage\": 0.7, \"offer_code\": null, \"type\": \"RENEWAL\", \"id\": \"2700D251-95AF-4A28-A460-130A7CC23F66\", \"app_id\": \"app5b6fd8d088\"}, \"customer_info\": {\"original_app_user_id\": \"$RCAnonymousID:7fd423d73f8240edbc186360f14a3f97\", \"first_seen\": \"2022-04-20T00:11:30Z\", \"last_seen\": \"2022-04-20T01:06:49Z\", \"subscriptions\": {\"monthly_pro\": {\"purchase_date\": \"2022-04-20T01:08:18Z\", \"expires_date\": \"2022-04-20T01:13:18Z\", \"period_type\": \"normal\", \"original_purchase_date\": \"2022-02-25T04:21:45Z\", \"store\": \"app_store\", \"is_sandbox\": true, \"unsubscribe_detected_at\": null, \"billing_issues_detected_at\": null, \"grace_period_expires_date\": null, \"ownership_type\": \"PURCHASED\"}}, \"non_subscriptions\": {}, \"other_purchases\": {}, \"original_application_version\": \"1.0\", \"original_purchase_date\": \"2013-08-01T07:00:00Z\", \"entitlements\": {\"pro\": {\"expires_date\": \"2022-04-20T01:13:18Z\", \"purchase_date\": \"2022-04-20T01:08:18Z\", \"product_identifier\": \"monthly_pro\", \"grace_period_expires_date\": null}}, \"management_url\": \"https://apps.apple.com/account/subscriptions\"}, \"api_version\": \"1.0.0\"}",
  "signed_jws_body": "{\"token\": \"...\"}"
}

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.activeEntitlements.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

Did this page help you?