Skip to main content

I'm facing a challenge with managing trial offers for anonymous users on new devices
 

The Problem

RevenueCat’s checkTrialOrIntroductoryEligibility is iOS-only, so I’ve built a workaround using allPurchasedProductIdentifiers to determine trial eligibility. It works like this:

 

const customerInfo = (await Purchases.getCustomerInfo()).customerInfo;

const numPurchases = customerInfo.allPurchasedProductIdentifiers.length;

if (numPurchases > 0) {
setShowTrialOffer(false);
}

 

This works as long as the user stays on the same device because RevenueCat caches the Anonymous ID. However, if the user:

  1. Starts a free trial
  2. Cancels the trial before it ends
  3. Deletes and reinstalls the app (or switches devices)

RevenueCat creates a new Anonymous ID when the user reopens the app. As a result, allPurchasedProductIdentifiers will be empty. This allows the user to start another free trial, repeating the process indefinitely.

 

Potential Solution: syncPurchases

Calling restorePurchases could prevent this, but it may trigger OS-level sign-in prompts, so RevenueCat recommends syncPurchases instead. However, the documentation is unclear:

  • General Docs:

    "syncPurchases allows you to programmatically trigger a restore. This method, like restorePurchases, reactivates any content previously purchased from the same store account."

  • SDK Docs:

    "syncPurchases sends all purchases to the RevenueCat backend. Call this when using your own subscription implementation anytime a sync is needed, like after a successful purchase."

These descriptions seem contradictory:

  • Does syncPurchases pull past purchases from the app stores?
  • Or does it just sync purchases from my app to RevenueCat?

Key Questions

If syncPurchases does pull past purchases from the app stores, what happens in this scenario?

  1. A user starts a trial (RevenueCat creates AnonymousAppUserID#1)
  2. The user deletes and reinstalls the app (RevenueCat creates AnonymousAppUserID#2)
  3. The user opens the app, and I call syncPurchases.

After calling syncPurchases:

  • Will CustomerInfo.originalAppUserId return AnonymousAppUserID#1?
  • Will CustomerInfo.allPurchasedProductIdentifiers include the original trial?
  • Will future webhooks for the user have AnonymousAppUserID#1 in the original_app_user_id field?

Any clarity would be greatly appreciated!

Chris

Hi, syncPurchases does the same thing as restorePurchases, just programatically. Both methods will pull all past purchases from the app stores associated with your app. 

 

Will CustomerInfo.originalAppUserId return AnonymousAppUserID#1?

The original_app_user_id will be the first seen alias. I believe in your case it would be the AnonymousAppUserID#2 as you would be transferring purchases from the AnonymousAppUserID#1 which would merge the users together, but it depends on which gets merged first.

 

Will CustomerInfo.allPurchasedProductIdentifiers include the original trial?

Yes it will as the users and their purchases are merged.

 

Will future webhooks for the user have AnonymousAppUserID#1 in the original_app_user_id field?

This depends on the above.


Thanks ​@Haley Pace 

I kept digging into this, and after half a day of testing, I found that the original_app_user_id  is  AnonymousAppUserID#1 after calling  syncPurchases() .

Hopefully, this helps anyone else looking for this answer.

Take care,


Chris 


Reply