diff --git a/code_blocks/integrations/attribution/adjust_4.kt b/code_blocks/integrations/attribution/adjust_4.kt new file mode 100644 index 00000000..44759bc1 --- /dev/null +++ b/code_blocks/integrations/attribution/adjust_4.kt @@ -0,0 +1,20 @@ +import com.adjust.sdk.Adjust +import com.adjust.sdk.AdjustConfig +import com.revenuecat.purchases.Purchases + +Purchases.configure(this, "public_sdk_key") + +// Automatically collect the $gpsAdId and $ip values +Purchases.sharedInstance.collectDeviceIdentifiers() + +// Set the Adjust Id on app launch if it exists +Adjust.getAdid()?.let { + Purchases.sharedInstance.setAdjustID(it) +} + +// IMPORTANT: Set the Adjust Id when it becomes available, if it didn't exist on app launch +val config = AdjustConfig(this, "yourAppToken", AdjustConfig.ENVIRONMENT_SANDBOX) +config.onAttributionChangedListener = { attribution -> + Purchases.sharedInstance.collectDeviceIdentifiers() + Purchases.sharedInstance.setAdjustID(attribution.adid) +} diff --git a/code_blocks/integrations/attribution/adjust_5.ts b/code_blocks/integrations/attribution/adjust_5.ts new file mode 100644 index 00000000..b8762dca --- /dev/null +++ b/code_blocks/integrations/attribution/adjust_5.ts @@ -0,0 +1,16 @@ +import Purchases from 'react-native-purchases'; +import { Adjust } from 'react-native-adjust'; + +Purchases.configure({ apiKey: 'public_sdk_key' }); +Purchases.collectDeviceIdentifiers(); + +Adjust.getAdid().then(adid => { + if (adid) { + Purchases.setAdjustID(adid); + } +}); + +Adjust.addAttributionChangedListener(attribution => { + Purchases.collectDeviceIdentifiers(); + Purchases.setAdjustID(attribution.adid); +}); diff --git a/code_blocks/integrations/attribution/adjust_6.dart b/code_blocks/integrations/attribution/adjust_6.dart new file mode 100644 index 00000000..c2e4997b --- /dev/null +++ b/code_blocks/integrations/attribution/adjust_6.dart @@ -0,0 +1,17 @@ +import 'package:adjust_sdk/adjust.dart'; +import 'package:purchases_flutter/purchases_flutter.dart'; + +Future init() async { + await Purchases.configure(PurchasesConfiguration('public_sdk_key')); + await Purchases.collectDeviceIdentifiers(); + + final adid = await Adjust.getAdid(); + if (adid != null) { + await Purchases.setAdjustID(adid); + } + + Adjust.addAttributionChangedListener((attribution) { + Purchases.collectDeviceIdentifiers(); + Purchases.setAdjustID(attribution.adid); + }); +} diff --git a/code_blocks/integrations/attribution/apple-search-ads_7.js.txt b/code_blocks/integrations/attribution/apple-search-ads_7.js.txt new file mode 100644 index 00000000..d9802e7c --- /dev/null +++ b/code_blocks/integrations/attribution/apple-search-ads_7.js.txt @@ -0,0 +1,10 @@ +import Purchases from 'react-native-purchases'; +import { requestTrackingPermission } from 'react-native-tracking-transparency'; + +async function setupAppleSearchAds() { + await Purchases.configure({ apiKey: 'public_sdk_key' }); + const status = await requestTrackingPermission(); + if (status === 'authorized') { + await Purchases.enableAdServicesAttributionTokenCollection(); + } +} diff --git a/code_blocks/integrations/attribution/apple-search-ads_8.dart b/code_blocks/integrations/attribution/apple-search-ads_8.dart new file mode 100644 index 00000000..408b13aa --- /dev/null +++ b/code_blocks/integrations/attribution/apple-search-ads_8.dart @@ -0,0 +1,10 @@ +import 'package:purchases_flutter/purchases_flutter.dart'; +import 'package:app_tracking_transparency/app_tracking_transparency.dart'; + +Future setupAppleSearchAds() async { + await Purchases.configure(PurchasesConfiguration('public_sdk_key')); + final status = await AppTrackingTransparency.requestTrackingAuthorization(); + if (status == TrackingStatus.authorized) { + await Purchases.enableAdServicesAttributionTokenCollection(); + } +} diff --git a/code_blocks/integrations/attribution/appsflyer_3.ts b/code_blocks/integrations/attribution/appsflyer_3.ts new file mode 100644 index 00000000..b543e5dd --- /dev/null +++ b/code_blocks/integrations/attribution/appsflyer_3.ts @@ -0,0 +1,28 @@ +import Purchases from 'react-native-purchases'; +import appsFlyer from 'react-native-appsflyer'; + +async function initRevenueCatAndAppsFlyer() { + // 1. Configure RevenueCat first + await Purchases.configure({ apiKey: 'public_sdk_key' }); + + // 2. Collect device identifiers: $gpsAdId, $ip (automatically handles platform-specifics) + await Purchases.collectDeviceIdentifiers(); + + // 3. Initialize AppsFlyer before retrieving UID + appsFlyer.initSdk( + { + devKey: 'your_af_dev_key', + isDebug: false, + appId: 'your_ios_app_id', // required only for iOS + }, + (result) => console.log('AppsFlyer initialized:', result), + (error) => console.error('AppsFlyer init error:', error) + ); + + // 4. Get the AppsFlyer ID and set it to RevenueCat + appsFlyer.getAppsFlyerUID((err, uid) => { + if (!err && uid) { + Purchases.setAppsflyerId(uid); + } + }); +} diff --git a/code_blocks/integrations/attribution/appsflyer_4.dart b/code_blocks/integrations/attribution/appsflyer_4.dart new file mode 100644 index 00000000..40b65b4e --- /dev/null +++ b/code_blocks/integrations/attribution/appsflyer_4.dart @@ -0,0 +1,13 @@ +import 'package:purchases_flutter/purchases_flutter.dart'; +import 'package:appsflyer_sdk/appsflyer_sdk.dart'; + +Future init() async { + await Purchases.configure(PurchasesConfiguration('public_sdk_key')); + Purchases.collectDeviceIdentifiers(); + + final appsflyerSdk = AppsFlyerSdk(AppsFlyerOptions(afDevKey: 'afDevKey', appId: '123')); + final uid = await appsflyerSdk.getAppsFlyerUID(); + if (uid != null) { + await Purchases.setAppsflyerId(uid); + } +} diff --git a/code_blocks/integrations/attribution/branch_1.dart b/code_blocks/integrations/attribution/branch_1.dart new file mode 100644 index 00000000..66660843 --- /dev/null +++ b/code_blocks/integrations/attribution/branch_1.dart @@ -0,0 +1,11 @@ +import 'package:flutter_branch_sdk/flutter_branch_sdk.dart'; +import 'package:purchases_flutter/purchases_flutter.dart'; + +// login +FlutterBranchSdk.setIdentity('my_app_user_id'); + +// Optional: Use a different App User ID between Branch and RevenueCat +Purchases.setAttributes({'\$branchId': ''}); + +// logout +FlutterBranchSdk.logout(); diff --git a/code_blocks/integrations/attribution/branch_1.kt b/code_blocks/integrations/attribution/branch_1.kt new file mode 100644 index 00000000..1c663a74 --- /dev/null +++ b/code_blocks/integrations/attribution/branch_1.kt @@ -0,0 +1,11 @@ +import io.branch.referral.Branch +import com.revenuecat.purchases.Purchases + +// login +Branch.getInstance().setIdentity("my_app_user_id") + +// Optional: Use a different App User ID between Branch and RevenueCat +Purchases.sharedInstance.setAttributes(mapOf("\$branchId" to "")) + +// logout +Branch.getInstance().logout() diff --git a/code_blocks/integrations/attribution/branch_5.dart b/code_blocks/integrations/attribution/branch_5.dart new file mode 100644 index 00000000..be19cbe2 --- /dev/null +++ b/code_blocks/integrations/attribution/branch_5.dart @@ -0,0 +1,6 @@ +import 'package:purchases_flutter/purchases_flutter.dart'; + +Future init() async { + await Purchases.configure(PurchasesConfiguration('public_sdk_key')); + await Purchases.collectDeviceIdentifiers(); +} diff --git a/code_blocks/integrations/attribution/facebook-ads_5.dart b/code_blocks/integrations/attribution/facebook-ads_5.dart new file mode 100644 index 00000000..69346070 --- /dev/null +++ b/code_blocks/integrations/attribution/facebook-ads_5.dart @@ -0,0 +1,7 @@ +import 'package:purchases_flutter/purchases_flutter.dart'; +import 'package:facebook_app_events/facebook_app_events.dart'; + +Future init() async { + await Purchases.configure(PurchasesConfiguration('public_sdk_key')); + FacebookAppEvents().activateApp(); +} diff --git a/code_blocks/integrations/attribution/facebook-ads_5.js.txt b/code_blocks/integrations/attribution/facebook-ads_5.js.txt new file mode 100644 index 00000000..9ef1bb5d --- /dev/null +++ b/code_blocks/integrations/attribution/facebook-ads_5.js.txt @@ -0,0 +1,7 @@ +import Purchases from 'react-native-purchases'; +import { AppEventsLogger } from 'react-native-fbsdk-next'; + +async function init() { + await Purchases.configure({ apiKey: 'public_sdk_key' }); + AppEventsLogger.activateApp(); +} diff --git a/code_blocks/integrations/attribution/facebook-ads_5.kt b/code_blocks/integrations/attribution/facebook-ads_5.kt new file mode 100644 index 00000000..c300c696 --- /dev/null +++ b/code_blocks/integrations/attribution/facebook-ads_5.kt @@ -0,0 +1,12 @@ +import android.app.Application +import com.facebook.appevents.AppEventsLogger +import com.revenuecat.purchases.Purchases +import com.revenuecat.purchases.PurchasesConfiguration + +class MyApp : Application() { + override fun onCreate() { + super.onCreate() + Purchases.configure(PurchasesConfiguration.Builder(this, "public_sdk_key").build()) + AppEventsLogger.activateApp(this) + } +} diff --git a/code_blocks/integrations/attribution/kochava_1.swift b/code_blocks/integrations/attribution/kochava_1.swift new file mode 100644 index 00000000..e908e08a --- /dev/null +++ b/code_blocks/integrations/attribution/kochava_1.swift @@ -0,0 +1,8 @@ +import KochavaTracker +import Purchases + +Purchases.configure(withAPIKey: "public_sdk_key") + +Tracker.shared.retrieveDeviceId { deviceId in + Purchases.shared.attribution.setKochavaDeviceId(deviceId) +} diff --git a/code_blocks/integrations/attribution/kochava_3.ts b/code_blocks/integrations/attribution/kochava_3.ts new file mode 100644 index 00000000..f36923fe --- /dev/null +++ b/code_blocks/integrations/attribution/kochava_3.ts @@ -0,0 +1,7 @@ +import Purchases from 'react-native-purchases'; +import KochavaTracker from 'react-native-kochava-tracker'; + +Purchases.configure({ apiKey: 'public_sdk_key' }); + +const deviceId = await KochavaTracker.getInstallId(); +Purchases.setKochavaDeviceId(deviceId); diff --git a/code_blocks/integrations/attribution/kochava_4.dart b/code_blocks/integrations/attribution/kochava_4.dart new file mode 100644 index 00000000..d526369d --- /dev/null +++ b/code_blocks/integrations/attribution/kochava_4.dart @@ -0,0 +1,9 @@ +import 'package:kochava_tracker/kochava_tracker.dart'; +import 'package:purchases_flutter/purchases_flutter.dart'; + +Future init() async { + await Purchases.configure(PurchasesConfiguration('public_sdk_key')); + + final deviceId = await KochavaTracker.instance.getInstallId(); + await Purchases.setKochavaDeviceId(deviceId); +} diff --git a/code_blocks/integrations/attribution/singular_3.ts b/code_blocks/integrations/attribution/singular_3.ts new file mode 100644 index 00000000..cf93f7b0 --- /dev/null +++ b/code_blocks/integrations/attribution/singular_3.ts @@ -0,0 +1,4 @@ +import Purchases from 'react-native-purchases'; + +Purchases.configure({ apiKey: 'public_sdk_key' }); +Purchases.collectDeviceIdentifiers(); diff --git a/code_blocks/integrations/attribution/singular_4.dart b/code_blocks/integrations/attribution/singular_4.dart new file mode 100644 index 00000000..be19cbe2 --- /dev/null +++ b/code_blocks/integrations/attribution/singular_4.dart @@ -0,0 +1,6 @@ +import 'package:purchases_flutter/purchases_flutter.dart'; + +Future init() async { + await Purchases.configure(PurchasesConfiguration('public_sdk_key')); + await Purchases.collectDeviceIdentifiers(); +} diff --git a/code_blocks/integrations/attribution/tenjin_3.ts b/code_blocks/integrations/attribution/tenjin_3.ts new file mode 100644 index 00000000..9f4e588f --- /dev/null +++ b/code_blocks/integrations/attribution/tenjin_3.ts @@ -0,0 +1,5 @@ +import Purchases from 'react-native-purchases'; + +Purchases.configure({ apiKey: 'public_sdk_key' }); +Purchases.collectDeviceIdentifiers(); +Purchases.setTenjinAnalyticsInstallationID(tenjinAnalyticsId); diff --git a/code_blocks/integrations/attribution/tenjin_4.dart b/code_blocks/integrations/attribution/tenjin_4.dart new file mode 100644 index 00000000..96232b2b --- /dev/null +++ b/code_blocks/integrations/attribution/tenjin_4.dart @@ -0,0 +1,7 @@ +import 'package:purchases_flutter/purchases_flutter.dart'; + +Future init() async { + await Purchases.configure(PurchasesConfiguration('public_sdk_key')); + await Purchases.collectDeviceIdentifiers(); + await Purchases.setTenjinAnalyticsInstallationID(tenjinAnalyticsId); +} diff --git a/code_blocks/integrations/third-party-integrations/airship_1.dart b/code_blocks/integrations/third-party-integrations/airship_1.dart new file mode 100644 index 00000000..41ea0641 --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/airship_1.dart @@ -0,0 +1,12 @@ +import 'package:purchases_flutter/purchases_flutter.dart'; +import 'package:airship_flutter/airship_flutter.dart'; + +Future setAirshipChannel() async { + await Purchases.configure( + PurchasesConfiguration('public_sdk_key')..appUserId = 'my_app_user_id', + ); + + // Airship is configured in native code with your app key + final channelId = await Airship.channelId; + await Purchases.setAirshipChannelId(channelId); +} diff --git a/code_blocks/integrations/third-party-integrations/airship_1.ts b/code_blocks/integrations/third-party-integrations/airship_1.ts new file mode 100644 index 00000000..19c3a01d --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/airship_1.ts @@ -0,0 +1,13 @@ +import Purchases from '@revenuecat/purchases-react-native'; +import Airship from 'urbanairship-react-native'; + +async function setAirshipChannel() { + await Purchases.configure({ + apiKey: 'public_sdk_key', + appUserID: 'my_app_user_id', + }); + + // Airship is configured in native code with your app key + const channelId = await Airship.getChannelId(); + await Purchases.setAirshipChannelID(channelId); +} diff --git a/code_blocks/integrations/third-party-integrations/airship_5.dart b/code_blocks/integrations/third-party-integrations/airship_5.dart new file mode 100644 index 00000000..0ac1c3ab --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/airship_5.dart @@ -0,0 +1,9 @@ +import 'package:purchases_flutter/purchases_flutter.dart'; +import 'package:airship_flutter/airship_flutter.dart'; + +Future identifyAirshipUser() async { + await Purchases.configure( + PurchasesConfiguration('public_sdk_key')..appUserId = 'my_app_user_id', + ); + await Airship.identify('my_app_user_id'); +} diff --git a/code_blocks/integrations/third-party-integrations/airship_5.ts b/code_blocks/integrations/third-party-integrations/airship_5.ts new file mode 100644 index 00000000..de996f66 --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/airship_5.ts @@ -0,0 +1,7 @@ +import Purchases from '@revenuecat/purchases-react-native'; +import Airship from 'urbanairship-react-native'; + +async function identifyAirshipUser() { + await Purchases.configure({ apiKey: 'public_sdk_key', appUserID: 'my_app_user_id' }); + await Airship.identify('my_app_user_id'); +} diff --git a/code_blocks/integrations/third-party-integrations/amplitude_1.dart b/code_blocks/integrations/third-party-integrations/amplitude_1.dart new file mode 100644 index 00000000..299c1abd --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/amplitude_1.dart @@ -0,0 +1,12 @@ +import 'package:purchases_flutter/purchases_flutter.dart'; +import 'package:amplitude_flutter/amplitude.dart'; + +Future setup() async { + await Purchases.configure( + PurchasesConfiguration('public_sdk_key')..appUserId = 'my_app_user_id', + ); + final amplitude = Amplitude.getInstance(instanceName: 'default'); + await amplitude.init('amplitude_api_key', 'my_app_user_id'); + final deviceId = await amplitude.getDeviceId(); + await Purchases.setAttributes({'\$amplitudeDeviceId': deviceId}); +} diff --git a/code_blocks/integrations/third-party-integrations/amplitude_1.kt b/code_blocks/integrations/third-party-integrations/amplitude_1.kt new file mode 100644 index 00000000..62e0870e --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/amplitude_1.kt @@ -0,0 +1,13 @@ +import com.amplitude.api.Amplitude +import com.revenuecat.purchases.Purchases + +// Configure Purchases SDK +Purchases.configure(this, "public_sdk_key", appUserID = "my_app_user_id") + +// Configure Amplitude SDK +val amplitude = Amplitude.getInstance() +amplitude.initialize(this, "amplitude_api_key") +amplitude.userId = "my_app_user_id" + +// Optional User Alias Object attributes +Purchases.sharedInstance.setAttributes(mapOf("\$amplitudeDeviceId" to amplitude.deviceId)) diff --git a/code_blocks/integrations/third-party-integrations/amplitude_1.ts b/code_blocks/integrations/third-party-integrations/amplitude_1.ts new file mode 100644 index 00000000..0691ade1 --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/amplitude_1.ts @@ -0,0 +1,10 @@ +import Purchases from '@revenuecat/purchases-react-native'; +import { init, setUserId, getDeviceId } from '@amplitude/analytics-react-native'; + +async function setup() { + await Purchases.configure({ apiKey: 'public_sdk_key', appUserID: 'my_app_user_id' }); + await init('amplitude_api_key'); + setUserId('my_app_user_id'); + const deviceId = await getDeviceId(); + await Purchases.setAttributes({ '$amplitudeDeviceId': deviceId }); +} diff --git a/code_blocks/integrations/third-party-integrations/braze_1.dart b/code_blocks/integrations/third-party-integrations/braze_1.dart new file mode 100644 index 00000000..b4b98afb --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/braze_1.dart @@ -0,0 +1,13 @@ +import 'package:purchases_flutter/purchases_flutter.dart'; +import 'package:braze_plugin/braze_plugin.dart'; + +Future init() async { + await Purchases.configure( + PurchasesConfiguration('public_sdk_key')..appUserID = 'my_app_user_id', + ); + BrazePlugin.changeUser('my_app_user_id'); + await Purchases.setAttributes({ + '\$brazeAliasName': 'name', + '\$brazeAliasLabel': 'label', + }); +} diff --git a/code_blocks/integrations/third-party-integrations/braze_1.kt b/code_blocks/integrations/third-party-integrations/braze_1.kt new file mode 100644 index 00000000..3114ff26 --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/braze_1.kt @@ -0,0 +1,17 @@ +import android.app.Application +import com.braze.Braze +import com.revenuecat.purchases.Purchases + +class MyApplication : Application() { + override fun onCreate() { + super.onCreate() + Purchases.configure(this, "public_sdk_key", appUserID = "my_app_user_id") + Braze.getInstance(applicationContext).changeUser("my_app_user_id") + Purchases.sharedInstance.attribution.setAttributes( + mapOf( + "\$brazeAliasName" to "name", + "\$brazeAliasLabel" to "label" + ) + ) + } +} diff --git a/code_blocks/integrations/third-party-integrations/braze_1.ts b/code_blocks/integrations/third-party-integrations/braze_1.ts new file mode 100644 index 00000000..bfffa8ed --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/braze_1.ts @@ -0,0 +1,10 @@ +import Purchases from 'react-native-purchases'; +import braze from '@braze/react-native-sdk'; + +Purchases.configure({ apiKey: 'public_sdk_key', appUserID: 'my_app_user_id' }); +braze.changeUser('my_app_user_id'); + +Purchases.setAttributes({ + '$brazeAliasName': 'name', + '$brazeAliasLabel': 'label', +}); diff --git a/code_blocks/integrations/third-party-integrations/clevertap_1.dart b/code_blocks/integrations/third-party-integrations/clevertap_1.dart new file mode 100644 index 00000000..27ee1d8c --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/clevertap_1.dart @@ -0,0 +1,11 @@ +import 'package:purchases_flutter/purchases_flutter.dart'; +import 'package:clevertap_plugin/clevertap_plugin.dart'; + +Future syncCleverTapId() async { + await Purchases.configure( + PurchasesConfiguration('public_sdk_key')..appUserId = 'my_app_user_id', + ); + final cleverTapId = await CleverTapPlugin.profileGetCleverTapID(); + await Purchases.setAttributes({'\$cleverTapId': cleverTapId}); +} + diff --git a/code_blocks/integrations/third-party-integrations/clevertap_1.ts b/code_blocks/integrations/third-party-integrations/clevertap_1.ts new file mode 100644 index 00000000..467b1640 --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/clevertap_1.ts @@ -0,0 +1,9 @@ +import Purchases from '@revenuecat/purchases-react-native'; +import CleverTap from 'clevertap-react-native'; + +async function syncCleverTapId() { + await Purchases.configure({ apiKey: 'public_sdk_key', appUserID: 'my_app_user_id' }); + const cleverTapId = await CleverTap.getCleverTapID(); + await Purchases.setAttributes({ '$cleverTapId': cleverTapId }); +} + diff --git a/code_blocks/integrations/third-party-integrations/customerio_8.dart b/code_blocks/integrations/third-party-integrations/customerio_8.dart new file mode 100644 index 00000000..f5a05091 --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/customerio_8.dart @@ -0,0 +1,17 @@ +import 'package:purchases_flutter/purchases_flutter.dart'; +import 'package:customer_io/customer_io.dart'; + +Future setupRevenueCatWithCustomerIo() async { + // Configure RevenueCat first + final configuration = PurchasesConfiguration('public_sdk_key') + ..appUserId = 'your_app_user_id'; + await Purchases.configure(configuration); + + // Ensure Customer.io is initialized and identify has been called + final customerIoId = CustomerIO.instance.profileIdentifier; + + if (customerIoId != null) { + await Purchases.setAttributes({'\$customerioId': customerIoId}); + } +} + diff --git a/code_blocks/integrations/third-party-integrations/customerio_8.kt b/code_blocks/integrations/third-party-integrations/customerio_8.kt new file mode 100644 index 00000000..64615b62 --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/customerio_8.kt @@ -0,0 +1,20 @@ +import android.content.Context +import com.revenuecat.purchases.Purchases +import com.revenuecat.purchases.PurchasesConfiguration +import io.customer.sdk.CustomerIO + +fun setupRevenueCatWithCustomerIo(context: Context) { + // Configure RevenueCat first + val config = PurchasesConfiguration.Builder(context, "public_sdk_key") + .appUserID("your_app_user_id") + .build() + Purchases.configure(config) + + // Ensure Customer.io is initialized and identify has been called + val customerIoId = CustomerIO.instance().identifier + + customerIoId?.let { + Purchases.sharedInstance.setAttributes(mapOf("\$customerioId" to it)) + } +} + diff --git a/code_blocks/integrations/third-party-integrations/customerio_8.swift b/code_blocks/integrations/third-party-integrations/customerio_8.swift new file mode 100644 index 00000000..1c1a013a --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/customerio_8.swift @@ -0,0 +1,17 @@ +import RevenueCat +import CustomerIO + +func setupRevenueCatWithCustomerIo() { + // Configure RevenueCat first + Purchases.configure(withAPIKey: "public_sdk_key", appUserID: "your_app_user_id") + + // Ensure Customer.io is initialized and identify has been called + let customerIoId = CustomerIO.shared.identifier + + if let customerIoId = customerIoId { + Purchases.shared.attribution.setAttributes([ + "$customerioId": customerIoId + ]) + } +} + diff --git a/code_blocks/integrations/third-party-integrations/customerio_8.ts b/code_blocks/integrations/third-party-integrations/customerio_8.ts new file mode 100644 index 00000000..7bb52be3 --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/customerio_8.ts @@ -0,0 +1,15 @@ +import Purchases from '@revenuecat/purchases-react-native'; +import CustomerIO from '@customerio/react-native'; + +export async function setupRevenueCatWithCustomerIo() { + // Configure RevenueCat first + await Purchases.configure({ apiKey: 'public_sdk_key', appUserID: 'your_app_user_id' }); + + // Ensure Customer.io is initialized and identify has been called + const customerIoId = await CustomerIO.getIdentifier(); + + if (customerIoId) { + await Purchases.setAttributes({ '$customerioId': customerIoId }); + } +} + diff --git a/code_blocks/integrations/third-party-integrations/firebase-integration_1.dart b/code_blocks/integrations/third-party-integrations/firebase-integration_1.dart new file mode 100644 index 00000000..b1de8c66 --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/firebase-integration_1.dart @@ -0,0 +1,11 @@ +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:purchases_flutter/purchases_flutter.dart'; + +Future initPlatformState() async { + await Purchases.configure(PurchasesConfiguration('public_sdk_key')); + FirebaseAuth.instance.authStateChanges().listen((user) { + if (user != null) { + Purchases.logIn(user.uid); + } + }); +} diff --git a/code_blocks/integrations/third-party-integrations/firebase-integration_1.kt b/code_blocks/integrations/third-party-integrations/firebase-integration_1.kt new file mode 100644 index 00000000..91f13a09 --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/firebase-integration_1.kt @@ -0,0 +1,16 @@ +import android.app.Application +import com.google.firebase.auth.FirebaseAuth +import com.revenuecat.purchases.Purchases +import com.revenuecat.purchases.logIn + +class MyApplication : Application() { + override fun onCreate() { + super.onCreate() + Purchases.configure(this, "public_sdk_key") + FirebaseAuth.getInstance().addAuthStateListener { auth -> + auth.currentUser?.uid?.let { uid -> + Purchases.sharedInstance.logIn(uid) { _, _, _ -> } + } + } + } +} diff --git a/code_blocks/integrations/third-party-integrations/firebase-integration_1.ts b/code_blocks/integrations/third-party-integrations/firebase-integration_1.ts new file mode 100644 index 00000000..07ca8947 --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/firebase-integration_1.ts @@ -0,0 +1,10 @@ +import auth from '@react-native-firebase/auth'; +import Purchases from 'react-native-purchases'; + +Purchases.configure({ apiKey: 'public_sdk_key' }); + +auth().onAuthStateChanged(user => { + if (user) { + Purchases.logIn(user.uid); + } +}); diff --git a/code_blocks/integrations/third-party-integrations/firebase-integration_2.dart b/code_blocks/integrations/third-party-integrations/firebase-integration_2.dart new file mode 100644 index 00000000..651913a2 --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/firebase-integration_2.dart @@ -0,0 +1,10 @@ +import 'package:firebase_analytics/firebase_analytics.dart'; +import 'package:purchases_flutter/purchases_flutter.dart'; + +Future initPlatformState() async { + await Purchases.configure(PurchasesConfiguration('public_sdk_key')); + final instanceId = await FirebaseAnalytics.instance.appInstanceId; + if (instanceId != null) { + await Purchases.setFirebaseAppInstanceId(instanceId); + } +} diff --git a/code_blocks/integrations/third-party-integrations/firebase-integration_2.kt b/code_blocks/integrations/third-party-integrations/firebase-integration_2.kt new file mode 100644 index 00000000..1718061f --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/firebase-integration_2.kt @@ -0,0 +1,18 @@ +import android.app.Application +import com.google.firebase.analytics.ktx.analytics +import com.google.firebase.ktx.Firebase +import com.revenuecat.purchases.Purchases + +class MyApplication : Application() { + override fun onCreate() { + super.onCreate() + Purchases.configure(this, "public_sdk_key") + Firebase.analytics.appInstanceId.addOnCompleteListener { task -> + if (task.isSuccessful) { + task.result?.let { id -> + Purchases.sharedInstance.attribution.setFirebaseAppInstanceId(id) + } + } + } + } +} diff --git a/code_blocks/integrations/third-party-integrations/firebase-integration_2.ts b/code_blocks/integrations/third-party-integrations/firebase-integration_2.ts new file mode 100644 index 00000000..9d69de99 --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/firebase-integration_2.ts @@ -0,0 +1,8 @@ +import analytics from '@react-native-firebase/analytics'; +import Purchases from 'react-native-purchases'; + +async function init() { + Purchases.configure({ apiKey: 'public_sdk_key' }); + const instanceId = await analytics().getAppInstanceId(); + await Purchases.setFirebaseAppInstanceId(instanceId); +} diff --git a/code_blocks/integrations/third-party-integrations/iterable_1.dart b/code_blocks/integrations/third-party-integrations/iterable_1.dart new file mode 100644 index 00000000..74ecc615 --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/iterable_1.dart @@ -0,0 +1,18 @@ +import 'package:purchases_flutter/purchases_flutter.dart'; +import 'package:iterable_flutter/iterable_flutter.dart'; + +Future setup() async { + await Purchases.configure( + PurchasesConfiguration('public_sdk_key')..appUserId = 'my_app_user_id', + ); + await IterableFlutter.initialize(''); + await IterableFlutter.setEmail('user@example.com'); + await IterableFlutter.setUserId('user123'); + await Purchases.setAttributes({ + '\$email': 'user@example.com', + '\$iterableUserId': 'user123', + '\$iterableCampaignId': '123', + '\$iterableTemplateId': '123', + }); +} + diff --git a/code_blocks/integrations/third-party-integrations/iterable_1.kt b/code_blocks/integrations/third-party-integrations/iterable_1.kt new file mode 100644 index 00000000..1ec4f662 --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/iterable_1.kt @@ -0,0 +1,16 @@ +import com.iterable.iterableapi.IterableApi +import com.revenuecat.purchases.Purchases + +Purchases.configure(this, "public_sdk_key", appUserID = "my_app_user_id") +IterableApi.initialize(this, "") + +IterableApi.setEmail("user@example.com") +IterableApi.setUserId("user123") + +Purchases.sharedInstance.setAttributes(mapOf( + "\$email" to "user@example.com", + "\$iterableUserId" to "user123", + "\$iterableCampaignId" to "123", + "\$iterableTemplateId" to "123" +)) + diff --git a/code_blocks/integrations/third-party-integrations/mixpanel_1.dart b/code_blocks/integrations/third-party-integrations/mixpanel_1.dart new file mode 100644 index 00000000..746f595f --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/mixpanel_1.dart @@ -0,0 +1,26 @@ +import 'package:mixpanel_flutter/mixpanel_flutter.dart'; +import 'package:purchases_flutter/purchases_flutter.dart'; + +// Call this early in app initialization +Future setupMixpanelRevenueCat() async { + // 1. Configure RevenueCat + await Purchases.configure( + PurchasesConfiguration('public_sdk_key')..appUserId = 'your_app_user_id', + ); + + // 2. Initialize Mixpanel + final mixpanel = await Mixpanel.init( + 'MIXPANEL_TOKEN', + trackAutomaticEvents: false, + ); + + // 3. Identify the user in Mixpanel + mixpanel.identify('your_app_user_id'); + + // 4. Fetch Mixpanel distinct ID + final distinctId = await mixpanel.getDistinctId(); + if (distinctId != null) { + // 5. Send to RevenueCat for attribution + await Purchases.setMixpanelDistinctId(distinctId); + } +} diff --git a/code_blocks/integrations/third-party-integrations/mixpanel_1.kt b/code_blocks/integrations/third-party-integrations/mixpanel_1.kt new file mode 100644 index 00000000..83010948 --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/mixpanel_1.kt @@ -0,0 +1,13 @@ +import android.app.Application +import com.mixpanel.android.mpmetrics.MixpanelAPI +import com.revenuecat.purchases.Purchases + +class MyApplication : Application() { + override fun onCreate() { + super.onCreate() + Purchases.configure(this, "public_sdk_key", appUserID = "my_app_user_id") + val mixpanel = MixpanelAPI.getInstance(this, "MIXPANEL_TOKEN") + mixpanel.identify("my_app_user_id") + Purchases.sharedInstance.attribution.setMixpanelDistinctId(mixpanel.distinctId) + } +} diff --git a/code_blocks/integrations/third-party-integrations/mixpanel_1.ts b/code_blocks/integrations/third-party-integrations/mixpanel_1.ts new file mode 100644 index 00000000..d38d6942 --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/mixpanel_1.ts @@ -0,0 +1,26 @@ +import Purchases from 'react-native-purchases'; +import { Mixpanel } from 'mixpanel-react-native'; + +const mixpanel = new Mixpanel('MIXPANEL_TOKEN'); + +async function init() { + try { + // Configure RevenueCat first + await Purchases.configure({ + apiKey: 'public_sdk_key', + appUserID: 'my_app_user_id', + }); + + // Initialize Mixpanel + await mixpanel.init(); + await mixpanel.identify('my_app_user_id'); + + // Get and pass distinctId to RevenueCat + const distinctId = await mixpanel.getDistinctId(); + if (distinctId) { + await Purchases.setMixpanelDistinctId(distinctId); + } + } catch (e) { + console.warn('Error setting up Mixpanel + RevenueCat:', e); + } +} diff --git a/code_blocks/integrations/third-party-integrations/mparticle_1.dart b/code_blocks/integrations/third-party-integrations/mparticle_1.dart new file mode 100644 index 00000000..93c37909 --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/mparticle_1.dart @@ -0,0 +1,15 @@ +import 'package:mparticle_flutter/mparticle_flutter.dart'; +import 'package:purchases_flutter/purchases_flutter.dart'; + +Future setup() async { + await Purchases.configure( + PurchasesConfiguration('public_sdk_key')..appUserId = 'my_app_user_id', + ); + final options = MParticleOptions( + apiKey: 'API_KEY', + apiSecret: 'API_SECRET', + identityRequest: IdentityRequest(userId: 'my_app_user_id'), + ); + await MParticleFlutter.start(options); +} + diff --git a/code_blocks/integrations/third-party-integrations/mparticle_1.kt b/code_blocks/integrations/third-party-integrations/mparticle_1.kt new file mode 100644 index 00000000..4a3dcd66 --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/mparticle_1.kt @@ -0,0 +1,17 @@ +import com.mparticle.MParticle +import com.mparticle.MParticleOptions +import com.mparticle.identity.IdentityApiRequest +import com.revenuecat.purchases.Purchases + +val identityRequest = IdentityApiRequest.withEmptyUser().also { + it.userId = "my_app_user_id" +} + +val options = MParticleOptions.builder(this) + .credentials("API_KEY", "API_SECRET") + .identity(identityRequest) + .build() + +MParticle.start(this, options) +Purchases.configure(this, "public_sdk_key", appUserID = "my_app_user_id") + diff --git a/code_blocks/integrations/third-party-integrations/mparticle_1.ts b/code_blocks/integrations/third-party-integrations/mparticle_1.ts new file mode 100644 index 00000000..633d7147 --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/mparticle_1.ts @@ -0,0 +1,12 @@ +import MParticle from '@mparticle/react-native'; +import Purchases from '@revenuecat/purchases-react-native'; + +async function setup() { + await Purchases.configure({ apiKey: 'public_sdk_key', appUserID: 'my_app_user_id' }); + MParticle.init({ + apiKey: 'API_KEY', + apiSecret: 'API_SECRET', + }); + MParticle.Identity.login({ userIdentities: { customerId: 'my_app_user_id' } }); +} + diff --git a/code_blocks/integrations/third-party-integrations/mparticle_4.dart b/code_blocks/integrations/third-party-integrations/mparticle_4.dart new file mode 100644 index 00000000..b9e72045 --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/mparticle_4.dart @@ -0,0 +1,8 @@ +import 'package:mparticle_flutter/mparticle_flutter.dart'; +import 'package:purchases_flutter/purchases_flutter.dart'; + +Future logout() async { + await MParticleFlutter.identity.logout(); + await Purchases.reset(); +} + diff --git a/code_blocks/integrations/third-party-integrations/mparticle_4.kt b/code_blocks/integrations/third-party-integrations/mparticle_4.kt new file mode 100644 index 00000000..f72cb094 --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/mparticle_4.kt @@ -0,0 +1,8 @@ +import com.mparticle.MParticle +import com.mparticle.identity.IdentityApiRequest +import com.revenuecat.purchases.Purchases + +MParticle.getInstance()?.identity?.logout()?.addSuccessListener { + Purchases.sharedInstance.reset() +} + diff --git a/code_blocks/integrations/third-party-integrations/mparticle_4.ts b/code_blocks/integrations/third-party-integrations/mparticle_4.ts new file mode 100644 index 00000000..3e7ab397 --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/mparticle_4.ts @@ -0,0 +1,8 @@ +import MParticle from '@mparticle/react-native'; +import Purchases from '@revenuecat/purchases-react-native'; + +export async function logout() { + await MParticle.Identity.logout(); + await Purchases.reset(); +} + diff --git a/code_blocks/integrations/third-party-integrations/mparticle_7.dart b/code_blocks/integrations/third-party-integrations/mparticle_7.dart new file mode 100644 index 00000000..b3664ddb --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/mparticle_7.dart @@ -0,0 +1,11 @@ +import 'package:mparticle_flutter/mparticle_flutter.dart'; +import 'package:purchases_flutter/purchases_flutter.dart'; + +Future login() async { + final result = await MParticleFlutter.identity + .login(IdentityRequest(userId: 'my_app_user_id')); + final mPid = result.user.userId; + await Purchases.collectDeviceIdentifiers(); + await Purchases.setMparticleID(mPid.toString()); +} + diff --git a/code_blocks/integrations/third-party-integrations/mparticle_7.kt b/code_blocks/integrations/third-party-integrations/mparticle_7.kt new file mode 100644 index 00000000..73ca4fd0 --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/mparticle_7.kt @@ -0,0 +1,14 @@ +import com.mparticle.MParticle +import com.mparticle.identity.IdentityApiRequest +import com.revenuecat.purchases.Purchases + +val request = IdentityApiRequest.withEmptyUser().also { + it.userId = "my_app_user_id" +} + +MParticle.getInstance()?.identity?.login(request)?.addSuccessListener { result -> + val mPid = result.user.id + Purchases.sharedInstance.attribution.collectDeviceIdentifiers() + Purchases.sharedInstance.attribution.setMparticleID(mPid.toString()) +} + diff --git a/code_blocks/integrations/third-party-integrations/mparticle_7.ts b/code_blocks/integrations/third-party-integrations/mparticle_7.ts new file mode 100644 index 00000000..aa326c92 --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/mparticle_7.ts @@ -0,0 +1,10 @@ +import MParticle from '@mparticle/react-native'; +import Purchases from '@revenuecat/purchases-react-native'; + +export async function login() { + const result = await MParticle.Identity.login({ userIdentities: { customerId: 'my_app_user_id' } }); + const mPid = result.getUser().getId(); + await Purchases.collectDeviceIdentifiers(); + await Purchases.setMparticleID(String(mPid)); +} + diff --git a/code_blocks/integrations/third-party-integrations/onesignal_1.dart b/code_blocks/integrations/third-party-integrations/onesignal_1.dart new file mode 100644 index 00000000..22c188b3 --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/onesignal_1.dart @@ -0,0 +1,22 @@ +import 'package:onesignal_flutter/onesignal_flutter.dart'; +import 'package:purchases_flutter/purchases_flutter.dart'; + +Future initOneSignalRevenueCat() async { + await Purchases.configure(PurchasesConfiguration('')); + OneSignal.setAppId(''); + + OneSignal.shared.setSubscriptionObserver((changes) { + if (!changes.from.isSubscribed && changes.to.isSubscribed) { + final userId = changes.to.userId; + if (userId != null) { + Purchases.setOnesignalID(userId); + } + } + }); + + final deviceState = await OneSignal.shared.getDeviceState(); + final userId = deviceState?.userId; + if (userId != null) { + await Purchases.setOnesignalID(userId); + } +} diff --git a/code_blocks/integrations/third-party-integrations/onesignal_1.kt b/code_blocks/integrations/third-party-integrations/onesignal_1.kt new file mode 100644 index 00000000..6e4a73a5 --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/onesignal_1.kt @@ -0,0 +1,27 @@ +import android.app.Application +import com.onesignal.OneSignal +import com.onesignal.OSSubscriptionObserver +import com.onesignal.OSSubscriptionStateChanges +import com.revenuecat.purchases.Purchases +import com.revenuecat.purchases.PurchasesConfiguration + +class MyApp : Application(), OSSubscriptionObserver { + override fun onCreate() { + super.onCreate() + Purchases.configure(PurchasesConfiguration.Builder(this, "").build()) + + OneSignal.initWithContext(this) + OneSignal.setAppId("") + OneSignal.addSubscriptionObserver(this) + + OneSignal.getDeviceState()?.userId?.let { + Purchases.shared.attribution.setOnesignalID(it) + } + } + + override fun onOSSubscriptionChanged(state: OSSubscriptionStateChanges) { + if (!state.from.isSubscribed && state.to.isSubscribed) { + state.to.userId?.let { Purchases.shared.attribution.setOnesignalID(it) } + } + } +} diff --git a/code_blocks/integrations/third-party-integrations/onesignal_1.ts b/code_blocks/integrations/third-party-integrations/onesignal_1.ts new file mode 100644 index 00000000..ccd74f7b --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/onesignal_1.ts @@ -0,0 +1,20 @@ +import OneSignal, { OSSubscriptionChangedEvent } from 'react-native-onesignal'; +import Purchases from '@revenuecat/purchases-react-native'; + +export async function initOneSignalRevenueCat() { + await Purchases.configure({ apiKey: '' }); + OneSignal.setAppId(''); + + OneSignal.addSubscriptionObserver((event: OSSubscriptionChangedEvent) => { + const userId = event.to.userId; + if (userId) { + Purchases.setOnesignalID(userId); + } + }); + + const state = OneSignal.getDeviceState(); + const userId = state?.userId; + if (userId) { + await Purchases.setOnesignalID(userId); + } +} diff --git a/code_blocks/integrations/third-party-integrations/onesignal_14.dart b/code_blocks/integrations/third-party-integrations/onesignal_14.dart new file mode 100644 index 00000000..5365b0eb --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/onesignal_14.dart @@ -0,0 +1,19 @@ +import 'package:onesignal_flutter/onesignal_flutter.dart'; +import 'package:purchases_flutter/purchases_flutter.dart'; + +Future initOneSignalRevenueCat() async { + await Purchases.configure(PurchasesConfiguration('')); + + OneSignal.initialize(''); + OneSignal.User.addObserver((state) { + final onesignalId = state.current.onesignalId; + if (onesignalId != null) { + Purchases.setOnesignalUserID(onesignalId); + } + }); + + final onesignalId = OneSignal.User.onesignalId; + if (onesignalId != null) { + await Purchases.setOnesignalUserID(onesignalId); + } +} diff --git a/code_blocks/integrations/third-party-integrations/onesignal_14.kt b/code_blocks/integrations/third-party-integrations/onesignal_14.kt new file mode 100644 index 00000000..3e024d9f --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/onesignal_14.kt @@ -0,0 +1,27 @@ +import android.app.Application +import com.onesignal.OneSignal +import com.onesignal.OSUserStateObserver +import com.onesignal.OSUserChangedState +import com.revenuecat.purchases.Purchases +import com.revenuecat.purchases.PurchasesConfiguration + +class MyApp : Application(), OSUserStateObserver { + override fun onCreate() { + super.onCreate() + Purchases.configure(PurchasesConfiguration.Builder(this, "").build()) + + OneSignal.initWithContext(this) + OneSignal.setAppId("") + OneSignal.User.addObserver(this) + + OneSignal.User.onesignalId?.let { id -> + Purchases.shared.attribution.setOnesignalUserID(id) + } + } + + override fun onUserStateChange(state: OSUserChangedState) { + state.current.onesignalId?.let { id -> + Purchases.shared.attribution.setOnesignalUserID(id) + } + } +} diff --git a/code_blocks/integrations/third-party-integrations/onesignal_14.ts b/code_blocks/integrations/third-party-integrations/onesignal_14.ts new file mode 100644 index 00000000..e3357f30 --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/onesignal_14.ts @@ -0,0 +1,19 @@ +import OneSignal, { UserChangedState } from 'react-native-onesignal'; +import Purchases from '@revenuecat/purchases-react-native'; + +export async function initOneSignalRevenueCat() { + await Purchases.configure({ apiKey: '' }); + + OneSignal.initialize(''); + OneSignal.User.addObserver((state: UserChangedState) => { + const onesignalId = state.current.onesignalId; + if (onesignalId) { + Purchases.setOnesignalUserID(onesignalId); + } + }); + + const onesignalId = OneSignal.User.onesignalId; + if (onesignalId) { + await Purchases.setOnesignalUserID(onesignalId); + } +} diff --git a/code_blocks/integrations/third-party-integrations/posthog_8.dart b/code_blocks/integrations/third-party-integrations/posthog_8.dart new file mode 100644 index 00000000..2990b263 --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/posthog_8.dart @@ -0,0 +1,6 @@ +import 'package:purchases_flutter/purchases_flutter.dart'; + +Future syncPostHogUserId(String posthogUserId) async { + await Purchases.setAttributes({'\$posthogUserId': posthogUserId}); +} + diff --git a/code_blocks/integrations/third-party-integrations/posthog_8.kt b/code_blocks/integrations/third-party-integrations/posthog_8.kt new file mode 100644 index 00000000..5c09449c --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/posthog_8.kt @@ -0,0 +1,5 @@ +import com.revenuecat.purchases.Purchases + +val posthogUserId = "POSTHOG_USER_ID" +Purchases.sharedInstance.setAttributes(mapOf("\$posthogUserId" to posthogUserId)) + diff --git a/code_blocks/integrations/third-party-integrations/posthog_8.swift b/code_blocks/integrations/third-party-integrations/posthog_8.swift new file mode 100644 index 00000000..89479f7d --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/posthog_8.swift @@ -0,0 +1,5 @@ +import RevenueCat + +let posthogUserId = "POSTHOG_USER_ID" +Purchases.shared.attribution.setAttributes(["$posthogUserId": posthogUserId]) + diff --git a/code_blocks/integrations/third-party-integrations/posthog_8.ts b/code_blocks/integrations/third-party-integrations/posthog_8.ts new file mode 100644 index 00000000..bef9b639 --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/posthog_8.ts @@ -0,0 +1,6 @@ +import Purchases from '@revenuecat/purchases-react-native'; + +export async function syncPostHogUserId(posthogUserId: string) { + await Purchases.setAttributes({ '$posthogUserId': posthogUserId }); +} + diff --git a/code_blocks/integrations/third-party-integrations/segment_1.dart b/code_blocks/integrations/third-party-integrations/segment_1.dart new file mode 100644 index 00000000..0996cada --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/segment_1.dart @@ -0,0 +1,11 @@ +import 'package:purchases_flutter/purchases_flutter.dart'; +import 'package:segment_flutter/segment_flutter.dart'; + +Future setup() async { + await Purchases.configure( + PurchasesConfiguration('public_sdk_key')..appUserId = 'my_app_user_id', + ); + final analytics = SegmentFlutter(writeKey: 'SEGMENT_WRITE_KEY'); + analytics.identify(userId: 'my_app_user_id'); +} + diff --git a/code_blocks/integrations/third-party-integrations/segment_1.kt b/code_blocks/integrations/third-party-integrations/segment_1.kt new file mode 100644 index 00000000..a1827a45 --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/segment_1.kt @@ -0,0 +1,6 @@ +import com.segment.analytics.Analytics +import com.revenuecat.purchases.Purchases + +Purchases.configure(this, "public_sdk_key", appUserID = "my_app_user_id") +Analytics.with(this).identify("my_app_user_id") + diff --git a/code_blocks/integrations/third-party-integrations/segment_1.ts b/code_blocks/integrations/third-party-integrations/segment_1.ts new file mode 100644 index 00000000..ddd36256 --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/segment_1.ts @@ -0,0 +1,9 @@ +import Purchases from '@revenuecat/purchases-react-native'; +import { createClient } from '@segment/analytics-react-native'; + +async function setup() { + await Purchases.configure({ apiKey: 'public_sdk_key', appUserID: 'my_app_user_id' }); + const segment = createClient({ writeKey: 'SEGMENT_WRITE_KEY' }); + segment.identify('my_app_user_id'); +} + diff --git a/code_blocks/integrations/third-party-integrations/statsig_10.dart b/code_blocks/integrations/third-party-integrations/statsig_10.dart new file mode 100644 index 00000000..6de74fa4 --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/statsig_10.dart @@ -0,0 +1,16 @@ +import 'package:statsig/statsig.dart'; +import 'package:purchases_flutter/purchases_flutter.dart'; + +Future setupRevenueCatWithStatsig() async { + await Purchases.configure( + PurchasesConfiguration('public_sdk_key')..appUserId = 'your_app_user_id', + ); + + await Statsig.initialize( + 'STATSIG_CLIENT_KEY', + user: StatsigUser(userID: 'your_app_user_id'), + ); + + final stableID = Statsig.getStableID(); + await Purchases.setAttributes({'$statsigUserID': stableID}); +} diff --git a/code_blocks/integrations/third-party-integrations/statsig_10.kt b/code_blocks/integrations/third-party-integrations/statsig_10.kt new file mode 100644 index 00000000..4844e0b0 --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/statsig_10.kt @@ -0,0 +1,18 @@ +import android.content.Context +import com.revenuecat.purchases.Purchases +import com.revenuecat.purchases.PurchasesConfiguration +import com.statsig.androidsdk.Statsig +import com.statsig.androidsdk.StatsigUser + +suspend fun setupRevenueCatWithStatsig(context: Context) { + Purchases.configure( + PurchasesConfiguration.Builder(context, "public_sdk_key") + .appUserID("your_app_user_id") + .build() + ) + + Statsig.start(context, "STATSIG_CLIENT_KEY", StatsigUser(userID = "your_app_user_id")) + + val stableID = Statsig.getStableID() + Purchases.shared.attribution.setAttributes(mapOf("$statsigUserID" to stableID)) +} diff --git a/code_blocks/integrations/third-party-integrations/statsig_10.swift b/code_blocks/integrations/third-party-integrations/statsig_10.swift new file mode 100644 index 00000000..f3587760 --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/statsig_10.swift @@ -0,0 +1,10 @@ +import RevenueCat +import Statsig + +func setupRevenueCatWithStatsig() { + Purchases.configure(withAPIKey: "public_sdk_key", appUserID: "your_app_user_id") + Statsig.start(sdkKey: "STATSIG_CLIENT_KEY", user: StatsigUser(userID: "your_app_user_id")) + if let stableID = Statsig.getStableID() { + Purchases.shared.attribution.setAttributes(["$statsigUserID": stableID]) + } +} diff --git a/code_blocks/integrations/third-party-integrations/statsig_10.ts b/code_blocks/integrations/third-party-integrations/statsig_10.ts new file mode 100644 index 00000000..0bd6c768 --- /dev/null +++ b/code_blocks/integrations/third-party-integrations/statsig_10.ts @@ -0,0 +1,14 @@ +import { Statsig } from 'statsig-react-native'; +import Purchases from '@revenuecat/purchases-react-native'; + +export async function setupRevenueCatWithStatsig() { + await Purchases.configure({ + apiKey: 'public_sdk_key', + appUserID: 'your_app_user_id', + }); + + await Statsig.initialize('STATSIG_CLIENT_KEY', { userID: 'your_app_user_id' }); + + const stableID = Statsig.getStableID(); + await Purchases.setAttributes({ '$statsigUserID': stableID }); +} diff --git a/docs/integrations/attribution/adjust.mdx b/docs/integrations/attribution/adjust.mdx index 0ed99b28..8ba9df0b 100644 --- a/docs/integrations/attribution/adjust.mdx +++ b/docs/integrations/attribution/adjust.mdx @@ -43,6 +43,9 @@ These properties can be set manually, like any other [Customer Attributes](/cust import swiftContent from "@site/code_blocks/integrations/attribution/adjust_1.swift?raw"; import javaContent from "@site/code_blocks/integrations/attribution/adjust_2.java?raw"; +import kotlinContent from "@site/code_blocks/integrations/attribution/adjust_4.kt?raw"; +import reactContent from "@site/code_blocks/integrations/attribution/adjust_5.ts?raw"; +import flutterContent from "@site/code_blocks/integrations/attribution/adjust_6.dart?raw"; diff --git a/docs/integrations/attribution/apple-search-ads.mdx b/docs/integrations/attribution/apple-search-ads.mdx index 1b14941e..048fdff8 100644 --- a/docs/integrations/attribution/apple-search-ads.mdx +++ b/docs/integrations/attribution/apple-search-ads.mdx @@ -118,8 +118,16 @@ If the user rejects tracking, the Standard attribution data can still be collect To request consent from a user, implement the `requestTrackingAuthorization` method before enabling automatic collection: import swiftContent2 from "@site/code_blocks/integrations/attribution/apple-search-ads_6.swift?raw"; +import reactNativeContent2 from "@site/code_blocks/integrations/attribution/apple-search-ads_7.js.txt?raw"; +import flutterContent2 from "@site/code_blocks/integrations/attribution/apple-search-ads_8.dart?raw"; - + After automatic collection is enabled, Purchases will sync the attribution token with the RevenueCat backend. Please note that if you enable automatic collection _before_ requesting authorization, the attribution token will only be valid for Standard and not Detailed attribution data. diff --git a/docs/integrations/attribution/appsflyer.mdx b/docs/integrations/attribution/appsflyer.mdx index 696281a8..b78c6a3d 100644 --- a/docs/integrations/attribution/appsflyer.mdx +++ b/docs/integrations/attribution/appsflyer.mdx @@ -43,6 +43,8 @@ These properties can be set manually, like any other [Attributes](/customers/cus import swiftContent from "@site/code_blocks/integrations/attribution/appsflyer_1.swift?raw"; import kotlinContent from "@site/code_blocks/integrations/attribution/appsflyer_2.kt?raw"; +import reactContent from "@site/code_blocks/integrations/attribution/appsflyer_3.ts?raw"; +import flutterContent from "@site/code_blocks/integrations/attribution/appsflyer_4.dart?raw"; {/* Use the RCCodeBlock component to render the code blocks with tabs */} @@ -50,6 +52,8 @@ import kotlinContent from "@site/code_blocks/integrations/attribution/appsflyer_ tabs={[ { type: "swift", content: swiftContent }, { type: "kotlin", content: kotlinContent }, + { type: "ts", title: "React Native", content: reactContent }, + { type: "dart", title: "Flutter", content: flutterContent }, ]} /> diff --git a/docs/integrations/attribution/branch.mdx b/docs/integrations/attribution/branch.mdx index 953de085..a6c1547b 100644 --- a/docs/integrations/attribution/branch.mdx +++ b/docs/integrations/attribution/branch.mdx @@ -33,6 +33,8 @@ import swiftContent from "@site/code_blocks/integrations/attribution/branch_1.sw import objectiveCContent from "@site/code_blocks/integrations/attribution/branch_2.m?raw"; import javaContent from "@site/code_blocks/integrations/attribution/branch_3.java?raw"; import reactNativeContent from "@site/code_blocks/integrations/attribution/branch_4.js.txt?raw"; +import kotlinContent0 from "@site/code_blocks/integrations/attribution/branch_1.kt?raw"; +import flutterContent0 from "@site/code_blocks/integrations/attribution/branch_1.dart?raw"; @@ -67,6 +71,7 @@ import objectiveCContent2 from "@site/code_blocks/integrations/attribution/branc import kotlinContent from "@site/code_blocks/integrations/attribution/branch_7.kt?raw"; import reactNativeContent2 from "@site/code_blocks/integrations/attribution/branch_8.js.txt?raw"; import cordovaContent from "@site/code_blocks/integrations/attribution/branch_cordova.js.txt?raw"; +import flutterContent from "@site/code_blocks/integrations/attribution/branch_5.dart?raw"; {/* Use the RCCodeBlock component to render the code blocks with tabs */} @@ -77,6 +82,7 @@ import cordovaContent from "@site/code_blocks/integrations/attribution/branch_co { type: "kotlin", content: kotlinContent }, { type: "rn", content: reactNativeContent2 }, { type: "cordova", content: cordovaContent }, + { type: "flutter", content: flutterContent }, ]} /> diff --git a/docs/integrations/attribution/kochava.mdx b/docs/integrations/attribution/kochava.mdx index 7c69cfa4..73e51c8e 100644 --- a/docs/integrations/attribution/kochava.mdx +++ b/docs/integrations/attribution/kochava.mdx @@ -40,11 +40,21 @@ $kochavaDeviceId and $deviceVersion are supported on versions 5.4.0+ of the iOS When calling the `setKochavaDeviceId()` helper, all of the required customer attributes will be automatically set. Alternatively, these properties can be set manually, like any other [Attributes](/customers/customer-attributes). +import swiftContent from "@site/code_blocks/integrations/attribution/kochava_1.swift?raw"; import kotlinContent from "@site/code_blocks/integrations/attribution/kochava_2.kt?raw"; +import reactContent from "@site/code_blocks/integrations/attribution/kochava_3.ts?raw"; +import flutterContent from "@site/code_blocks/integrations/attribution/kochava_4.dart?raw"; {/* Use the RCCodeBlock component to render the code blocks with tabs */} - + You should make sure to set attributes after the _Purchases SDK_ is configured, and before the first purchase occurs. It's safe to set attributes multiple times, as only the new/updated values will be sent to RevenueCat. diff --git a/docs/integrations/attribution/meta-ads.mdx b/docs/integrations/attribution/meta-ads.mdx index 70145fa4..039b97f3 100644 --- a/docs/integrations/attribution/meta-ads.mdx +++ b/docs/integrations/attribution/meta-ads.mdx @@ -82,10 +82,18 @@ To continue to track install and usage events in Meta, follow the steps in the n As noted above, you'll need to disable all client side tracking of revenue to prevent double counting of revenue in Meta Ads Manager. To continue tracking install and usage events, you'll need to call Meta's 'activate app' event after configuration: import swiftContent2 from "@site/code_blocks/integrations/attribution/facebook-ads_5.swift?raw"; +import kotlinContent2 from "@site/code_blocks/integrations/attribution/facebook-ads_5.kt?raw"; +import reactNativeContent2 from "@site/code_blocks/integrations/attribution/facebook-ads_5.js.txt?raw"; +import flutterContent2 from "@site/code_blocks/integrations/attribution/facebook-ads_5.dart?raw"; -{/* Use the RCCodeBlock component to render the code blocks with tabs */} - - + You can see Meta's App Events Reference [here](https://developers.facebook.com/docs/app-events/reference). diff --git a/docs/integrations/attribution/singular.mdx b/docs/integrations/attribution/singular.mdx index bb07bce3..17852891 100644 --- a/docs/integrations/attribution/singular.mdx +++ b/docs/integrations/attribution/singular.mdx @@ -38,11 +38,15 @@ These properties can be set manually, like any other [Attributes](/customers/cus import swiftContent from "@site/code_blocks/integrations/attribution/singular_1.swift?raw"; import kotlinContent from "@site/code_blocks/integrations/attribution/singular_2.kt?raw"; +import reactContent from "@site/code_blocks/integrations/attribution/singular_3.ts?raw"; +import flutterContent from "@site/code_blocks/integrations/attribution/singular_4.dart?raw"; diff --git a/docs/integrations/attribution/tenjin.mdx b/docs/integrations/attribution/tenjin.mdx index add51859..bdd4c617 100644 --- a/docs/integrations/attribution/tenjin.mdx +++ b/docs/integrations/attribution/tenjin.mdx @@ -39,11 +39,15 @@ These properties can be set manually, like any other [Customer Attributes](/cust import swiftContent from "@site/code_blocks/integrations/attribution/tenjin_1.swift?raw"; import kotlinContent from "@site/code_blocks/integrations/attribution/tenjin_2.kt?raw"; +import reactContent from "@site/code_blocks/integrations/attribution/tenjin_3.ts?raw"; +import flutterContent from "@site/code_blocks/integrations/attribution/tenjin_4.dart?raw"; diff --git a/docs/integrations/third-party-integrations/airship.mdx b/docs/integrations/third-party-integrations/airship.mdx index 6bbfd701..b02806c2 100644 --- a/docs/integrations/third-party-integrations/airship.mdx +++ b/docs/integrations/third-party-integrations/airship.mdx @@ -57,6 +57,8 @@ import swiftContent from "@site/code_blocks/integrations/third-party-integration import objectiveCContent from "@site/code_blocks/integrations/third-party-integrations/airship_2.m?raw"; import kotlinContent from "@site/code_blocks/integrations/third-party-integrations/airship_3.kt?raw"; import javaContent from "@site/code_blocks/integrations/third-party-integrations/airship_4.java?raw"; +import reactContent from "@site/code_blocks/integrations/third-party-integrations/airship_1.ts?raw"; +import flutterContent from "@site/code_blocks/integrations/third-party-integrations/airship_1.dart?raw"; @@ -75,6 +79,8 @@ import swiftContent2 from "@site/code_blocks/integrations/third-party-integratio import objectiveCContent2 from "@site/code_blocks/integrations/third-party-integrations/airship_6.m?raw"; import kotlinContent2 from "@site/code_blocks/integrations/third-party-integrations/airship_7.kt?raw"; import javaContent2 from "@site/code_blocks/integrations/third-party-integrations/airship_8.java?raw"; +import reactContent2 from "@site/code_blocks/integrations/third-party-integrations/airship_5.ts?raw"; +import flutterContent2 from "@site/code_blocks/integrations/third-party-integrations/airship_5.dart?raw"; diff --git a/docs/integrations/third-party-integrations/amplitude.mdx b/docs/integrations/third-party-integrations/amplitude.mdx index e4b35058..922dbecb 100644 --- a/docs/integrations/third-party-integrations/amplitude.mdx +++ b/docs/integrations/third-party-integrations/amplitude.mdx @@ -52,12 +52,18 @@ Configure the Amplitude SDK with the same App User Id as RevenueCat or use the ` import swiftContent from "@site/code_blocks/integrations/third-party-integrations/amplitude_1.swift?raw"; import objectiveCContent from "@site/code_blocks/integrations/third-party-integrations/amplitude_2.m?raw"; import javaContent from "@site/code_blocks/integrations/third-party-integrations/amplitude_3.java?raw"; +import kotlinContent from "@site/code_blocks/integrations/third-party-integrations/amplitude_1.kt?raw"; +import reactContent from "@site/code_blocks/integrations/third-party-integrations/amplitude_1.ts?raw"; +import flutterContent from "@site/code_blocks/integrations/third-party-integrations/amplitude_1.dart?raw"; diff --git a/docs/integrations/third-party-integrations/braze.mdx b/docs/integrations/third-party-integrations/braze.mdx index e6c21841..8f41bb18 100644 --- a/docs/integrations/third-party-integrations/braze.mdx +++ b/docs/integrations/third-party-integrations/braze.mdx @@ -73,12 +73,18 @@ Configure the Braze SDK with the same App User Id as RevenueCat or use the `.cha import swiftContent from "@site/code_blocks/integrations/third-party-integrations/braze_1.swift?raw"; import objectiveCContent from "@site/code_blocks/integrations/third-party-integrations/braze_2.m?raw"; import javaContent from "@site/code_blocks/integrations/third-party-integrations/braze_3.java?raw"; +import kotlinContent from "@site/code_blocks/integrations/third-party-integrations/braze_1.kt?raw"; +import reactContent from "@site/code_blocks/integrations/third-party-integrations/braze_1.ts?raw"; +import flutterContent from "@site/code_blocks/integrations/third-party-integrations/braze_1.dart?raw"; diff --git a/docs/integrations/third-party-integrations/clevertap.mdx b/docs/integrations/third-party-integrations/clevertap.mdx index 2de5e244..a9088727 100644 --- a/docs/integrations/third-party-integrations/clevertap.mdx +++ b/docs/integrations/third-party-integrations/clevertap.mdx @@ -56,6 +56,8 @@ import swiftContent from "@site/code_blocks/integrations/third-party-integration import objectiveCContent from "@site/code_blocks/integrations/third-party-integrations/clevertap_2.m?raw"; import kotlinContent from "@site/code_blocks/integrations/third-party-integrations/clevertap_3.kt?raw"; import javaContent from "@site/code_blocks/integrations/third-party-integrations/clevertap_4.java?raw"; +import reactContent from "@site/code_blocks/integrations/third-party-integrations/clevertap_1.ts?raw"; +import flutterContent from "@site/code_blocks/integrations/third-party-integrations/clevertap_1.dart?raw"; diff --git a/docs/integrations/third-party-integrations/customerio.mdx b/docs/integrations/third-party-integrations/customerio.mdx index 77e1ca95..b4ae0fe6 100644 --- a/docs/integrations/third-party-integrations/customerio.mdx +++ b/docs/integrations/third-party-integrations/customerio.mdx @@ -47,6 +47,20 @@ For events that have revenue, such as trial conversions and renewals, RevenueCat In order to associate RevenueCat data with a Customer.io Person, the RevenueCat `$customerioId` [Attribute](/customers/customer-attributes) should be set in RevenueCat to the Person's `id`. If this field does not exist, RevenueCat will fallback to using the RevenueCat app user ID as the `id`. If there is no matching Person, it will be created automatically. You can read more about how the association works in Customer.io's [Identifying people](https://docs.customer.io/journeys/identifying-people/#identifiers) documentation. +import swiftContent from "@site/code_blocks/integrations/third-party-integrations/customerio_8.swift?raw"; +import kotlinContent from "@site/code_blocks/integrations/third-party-integrations/customerio_8.kt?raw"; +import reactContent from "@site/code_blocks/integrations/third-party-integrations/customerio_8.ts?raw"; +import flutterContent from "@site/code_blocks/integrations/third-party-integrations/customerio_8.dart?raw"; + + + ### 2. Send RevenueCat Events to Customer.io After you've set up the Purchase SDK and Customer.io SDK to have the same user identity, you can "turn on" the integration and configure the event names from the RevenueCat dashboard. diff --git a/docs/integrations/third-party-integrations/firebase-integration.mdx b/docs/integrations/third-party-integrations/firebase-integration.mdx index 4d79c1f5..98f4ce20 100644 --- a/docs/integrations/third-party-integrations/firebase-integration.mdx +++ b/docs/integrations/third-party-integrations/firebase-integration.mdx @@ -50,8 +50,18 @@ When connecting to Firebase, it's possible that you may see an error like: 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 swiftContent from "@site/code_blocks/integrations/third-party-integrations/firebase-integration_1.swift?raw"; +import kotlinContent from "@site/code_blocks/integrations/third-party-integrations/firebase-integration_1.kt?raw"; +import reactContent from "@site/code_blocks/integrations/third-party-integrations/firebase-integration_1.ts?raw"; +import flutterContent from "@site/code_blocks/integrations/third-party-integrations/firebase-integration_1.dart?raw"; - + ## 3. Send analytics events to Google Analytics @@ -62,8 +72,18 @@ In order to send subscriber lifecycle events to Google Analytics, you must set t Please ensure you're getting the app instance ID from the [Firebase Analytics](https://firebase.google.com/docs/analytics/get-started) package. import swiftContent2 from "@site/code_blocks/integrations/third-party-integrations/firebase-integration_2.swift?raw"; +import kotlinContent2 from "@site/code_blocks/integrations/third-party-integrations/firebase-integration_2.kt?raw"; +import reactContent2 from "@site/code_blocks/integrations/third-party-integrations/firebase-integration_2.ts?raw"; +import flutterContent2 from "@site/code_blocks/integrations/third-party-integrations/firebase-integration_2.dart?raw"; - + :::warning Setting an incorrect app instance ID will prevent events from displaying in Google Analytics. diff --git a/docs/integrations/third-party-integrations/iterable.mdx b/docs/integrations/third-party-integrations/iterable.mdx index e2ca334e..143cccd2 100644 --- a/docs/integrations/third-party-integrations/iterable.mdx +++ b/docs/integrations/third-party-integrations/iterable.mdx @@ -58,6 +58,8 @@ To attribute an event to an Iterable Campaign ID and/or Template ID, set the `$i import swiftContent from "@site/code_blocks/integrations/third-party-integrations/iterable_1.swift?raw"; import objectiveCContent from "@site/code_blocks/integrations/third-party-integrations/iterable_2.m?raw"; import javaContent from "@site/code_blocks/integrations/third-party-integrations/iterable_3.java?raw"; +import kotlinContent from "@site/code_blocks/integrations/third-party-integrations/iterable_1.kt?raw"; +import flutterContent from "@site/code_blocks/integrations/third-party-integrations/iterable_1.dart?raw"; import reactNativeContent from "@site/code_blocks/integrations/third-party-integrations/iterable_4.js.txt?raw"; import curlContent from "@site/code_blocks/integrations/third-party-integrations/iterable_5.curl?raw"; @@ -66,7 +68,9 @@ import curlContent from "@site/code_blocks/integrations/third-party-integrations { type: "swift", content: swiftContent }, { type: "objc", content: objectiveCContent }, { type: "java", content: javaContent }, + { type: "kotlin", content: kotlinContent }, { type: "rn", content: reactNativeContent, name: "React Native" }, + { type: "dart", title: "Flutter", content: flutterContent }, { type: "curl", content: curlContent }, ]} /> diff --git a/docs/integrations/third-party-integrations/mixpanel.mdx b/docs/integrations/third-party-integrations/mixpanel.mdx index ad24027a..c2a89c21 100644 --- a/docs/integrations/third-party-integrations/mixpanel.mdx +++ b/docs/integrations/third-party-integrations/mixpanel.mdx @@ -58,12 +58,18 @@ If a user has that attribute set it will be used instead of the RevenueCat App U import swiftContent from "@site/code_blocks/integrations/third-party-integrations/mixpanel_1.swift?raw"; import objectiveCContent from "@site/code_blocks/integrations/third-party-integrations/mixpanel_2.m?raw"; import javaContent from "@site/code_blocks/integrations/third-party-integrations/mixpanel_3.java?raw"; +import kotlinContent from "@site/code_blocks/integrations/third-party-integrations/mixpanel_1.kt?raw"; +import reactContent from "@site/code_blocks/integrations/third-party-integrations/mixpanel_1.ts?raw"; +import flutterContent from "@site/code_blocks/integrations/third-party-integrations/mixpanel_1.dart?raw"; diff --git a/docs/integrations/third-party-integrations/mparticle.mdx b/docs/integrations/third-party-integrations/mparticle.mdx index d8c2fae3..7a6a0b7c 100644 --- a/docs/integrations/third-party-integrations/mparticle.mdx +++ b/docs/integrations/third-party-integrations/mparticle.mdx @@ -72,12 +72,18 @@ Create an `identityRequest` and add it to the `MParticleOptions` that you pass t import swiftContent from "@site/code_blocks/integrations/third-party-integrations/mparticle_1.swift?raw"; import objectiveCContent from "@site/code_blocks/integrations/third-party-integrations/mparticle_2.m?raw"; import javaContent from "@site/code_blocks/integrations/third-party-integrations/mparticle_3.java?raw"; +import kotlinContent from "@site/code_blocks/integrations/third-party-integrations/mparticle_1.kt?raw"; +import reactContent from "@site/code_blocks/integrations/third-party-integrations/mparticle_1.ts?raw"; +import flutterContent from "@site/code_blocks/integrations/third-party-integrations/mparticle_1.dart?raw"; @@ -86,24 +92,36 @@ mParticle also allows you to log a user in after starting the SDK and log a user import swiftContent2 from "@site/code_blocks/integrations/third-party-integrations/mparticle_4.swift?raw"; import objectiveCContent2 from "@site/code_blocks/integrations/third-party-integrations/mparticle_5.m?raw"; import javaContent2 from "@site/code_blocks/integrations/third-party-integrations/mparticle_6.java?raw"; +import kotlinContent2 from "@site/code_blocks/integrations/third-party-integrations/mparticle_4.kt?raw"; +import reactContent2 from "@site/code_blocks/integrations/third-party-integrations/mparticle_4.ts?raw"; +import flutterContent2 from "@site/code_blocks/integrations/third-party-integrations/mparticle_4.dart?raw"; import swiftContent3 from "@site/code_blocks/integrations/third-party-integrations/mparticle_7.swift?raw"; import objectiveCContent3 from "@site/code_blocks/integrations/third-party-integrations/mparticle_8.m?raw"; import javaContent3 from "@site/code_blocks/integrations/third-party-integrations/mparticle_9.java?raw"; +import kotlinContent3 from "@site/code_blocks/integrations/third-party-integrations/mparticle_7.kt?raw"; +import reactContent3 from "@site/code_blocks/integrations/third-party-integrations/mparticle_7.ts?raw"; +import flutterContent3 from "@site/code_blocks/integrations/third-party-integrations/mparticle_7.dart?raw"; diff --git a/docs/integrations/third-party-integrations/onesignal.mdx b/docs/integrations/third-party-integrations/onesignal.mdx index 975bc6cb..278b5f99 100644 --- a/docs/integrations/third-party-integrations/onesignal.mdx +++ b/docs/integrations/third-party-integrations/onesignal.mdx @@ -78,11 +78,17 @@ You can [listen for changes to the OneSignal Id through their SDK](https://docum import onesignalV11Content from "@site/code_blocks/integrations/third-party-integrations/onesignal_14.swift?raw"; import onesignalV11ContentSwiftUi from "@site/code_blocks/integrations/third-party-integrations/onesignal_15.swift?raw"; +import onesignalV11ContentKotlin from "@site/code_blocks/integrations/third-party-integrations/onesignal_14.kt?raw"; +import onesignalV11ContentReact from "@site/code_blocks/integrations/third-party-integrations/onesignal_14.ts?raw"; +import onesignalV11ContentFlutter from "@site/code_blocks/integrations/third-party-integrations/onesignal_14.dart?raw"; @@ -99,8 +105,18 @@ This property can be set manually, like any other [Attribute](/customers/custome You can listen for changes to the OneSignal Id through their SDK, and send the value to RevenueCat. If you already have OneSignal set up, you should make sure that you're also sending the OneSignal Id for users that are updating to the latest version of your app. import onesignalV9Content from "@site/code_blocks/integrations/third-party-integrations/onesignal_1.swift?raw"; +import onesignalV9ContentKotlin from "@site/code_blocks/integrations/third-party-integrations/onesignal_1.kt?raw"; +import onesignalV9ContentReact from "@site/code_blocks/integrations/third-party-integrations/onesignal_1.ts?raw"; +import onesignalV9ContentFlutter from "@site/code_blocks/integrations/third-party-integrations/onesignal_1.dart?raw"; - + ## 2. Send RevenueCat events into OneSignal diff --git a/docs/integrations/third-party-integrations/posthog.mdx b/docs/integrations/third-party-integrations/posthog.mdx index 4ccf23bc..998a7ba3 100644 --- a/docs/integrations/third-party-integrations/posthog.mdx +++ b/docs/integrations/third-party-integrations/posthog.mdx @@ -47,6 +47,20 @@ For events that have revenue, such as trial conversions and renewals, RevenueCat In order to associate RevenueCat data with a PostHog User, the RevenueCat `$posthogUserId` [Attribute](/customers/customer-attributes) should be set in RevenueCat. If this field does not exist, RevenueCat will fallback to the RevenueCat app user ID. You can read more about PostHog user profiles in PostHog's [Identifying users](https://posthog.com/docs/product-analytics/identify) documentation. +import swiftContent from "@site/code_blocks/integrations/third-party-integrations/posthog_8.swift?raw"; +import kotlinContent from "@site/code_blocks/integrations/third-party-integrations/posthog_8.kt?raw"; +import reactContent from "@site/code_blocks/integrations/third-party-integrations/posthog_8.ts?raw"; +import flutterContent from "@site/code_blocks/integrations/third-party-integrations/posthog_8.dart?raw"; + + + ### 2. Send RevenueCat Events to PostHog After you've set up the Purchase SDK and PostHog SDK to have the same user identity, you can "turn on" the integration and configure the event names from the RevenueCat dashboard. diff --git a/docs/integrations/third-party-integrations/segment.mdx b/docs/integrations/third-party-integrations/segment.mdx index f6d57617..495ae888 100644 --- a/docs/integrations/third-party-integrations/segment.mdx +++ b/docs/integrations/third-party-integrations/segment.mdx @@ -52,12 +52,18 @@ Use the `.identify()` method on the Segment SDK to set the same App User Id that import swiftContent from "@site/code_blocks/integrations/third-party-integrations/segment_1.swift?raw"; import objectiveCContent from "@site/code_blocks/integrations/third-party-integrations/segment_2.m?raw"; import javaContent from "@site/code_blocks/integrations/third-party-integrations/segment_3.java?raw"; +import kotlinContent from "@site/code_blocks/integrations/third-party-integrations/segment_1.kt?raw"; +import reactContent from "@site/code_blocks/integrations/third-party-integrations/segment_1.ts?raw"; +import flutterContent from "@site/code_blocks/integrations/third-party-integrations/segment_1.dart?raw"; diff --git a/docs/integrations/third-party-integrations/statsig.mdx b/docs/integrations/third-party-integrations/statsig.mdx index fac473db..3d9c17e3 100644 --- a/docs/integrations/third-party-integrations/statsig.mdx +++ b/docs/integrations/third-party-integrations/statsig.mdx @@ -41,6 +41,22 @@ The Statsig integration tracks the following events: In order to associate RevenueCat data with Statsig feature gate and/or experiment, the RevenueCat app user ID must match the Statsig User ID. You can read more about Statsig user IDs in their documentation [here](https://docs.statsig.com/server/pythonSDK#statsiguser). You can set up a custom app user ID in RevenueCat by following the instructions in our [Identifying Users](/customers/user-ids#provided-app-user-id) documentation. +If you're using Statsig's client-side SDK, forward the Statsig stable ID to RevenueCat so we can associate experiments with purchases. + +import statsigSwift from "@site/code_blocks/integrations/third-party-integrations/statsig_10.swift?raw"; +import statsigKotlin from "@site/code_blocks/integrations/third-party-integrations/statsig_10.kt?raw"; +import statsigReact from "@site/code_blocks/integrations/third-party-integrations/statsig_10.ts?raw"; +import statsigFlutter from "@site/code_blocks/integrations/third-party-integrations/statsig_10.dart?raw"; + + + ## 1. Enable RevenueCat integration with Statsig On the Statsig [Integration page](https://console.statsig.com/integrations) enable the RevenueCat integration.