Skip to main content

I am using RevenueCat's Flutter SDK to manage user subscriptions in my app. For associating user content in my database, I rely on the initial anonymous user ID generated by RevenueCat since i do not want to have to setup user accounts.

There is an issue though when a user deletes the app and reinstalls it, or installs the app on a new device and restores their purchase, RevenueCat generates a new Alias instead of using the original anonymous id. This is a problem because there is a maximum limit of 50 aliases.

Is there a way to make it so when the user restores a purchase it uses the original Anonymous App User ID instead of creating a new one? Here is the relevant portion of my code:

 

class SubscriptionProvider with ChangeNotifier {



bool _hasActiveSubscription = false;
String _activeEntitlement = '';
String _anonymousId = 'unpaidUser'; // Default to 'unpaidUser'



bool get hasActiveSubscription => _hasActiveSubscription;
String get activeEntitlement => _activeEntitlement;
String get anonymousId => _anonymousId;



Future<void> initialize() async {
print("Starting RevenueCat configuration...");
await configureRevenueCat();
print("RevenueCat configuration completed.");

print("Checking subscription status...");
await checkSubscriptionStatus();
print("Subscription status checked.");
}



Future<void> configureRevenueCat() async {
print('Configuring RevenueCat...');
try {
Purchases.setLogLevel(LogLevel.debug); // Use LogLevel.debug only during development

if (Platform.isIOS || Platform.isMacOS) {
var config = PurchasesConfiguration("");
await Purchases.configure(config);
} else if (Platform.isAndroid) {
var config = PurchasesConfiguration("");
await Purchases.configure(config);
}

// Fetch CustomerInfo after configuring the SDK
CustomerInfo purchaserInfo = await Purchases.getCustomerInfo();
String userId = purchaserInfo.originalAppUserId;

// Log in to RevenueCat with the originalAppUserId
await Purchases.logIn(userId);

print('RevenueCat configured and logged in successfully.');
} catch (e) {
print('Error configuring RevenueCat: $e');
// Optionally handle the error, e.g., retry or fallback
}
}



Future<void> checkSubscriptionStatus() async {
print('Checking subscription status...');
try {
CustomerInfo purchaserInfo = await Purchases.getCustomerInfo();
print('PurchaserInfo fetched: $purchaserInfo');
updateSubscriptionStatus(purchaserInfo);
} catch (e) {
print('Error fetching PurchaserInfo: $e');
loadSubscriptionStatusFromSharedPreferences(); // Fallback to SharedPreferences if online check fails
}
}



void updateSubscriptionStatus(CustomerInfo purchaserInfo) {
print('Updating subscription status...');

// Directly set the anonymous ID from the purchaserInfo
_anonymousId = purchaserInfo.originalAppUserId;
print('Anonymous ID set to: $_anonymousId');

_hasActiveSubscription = purchaserInfo.entitlements.active.isNotEmpty;
_activeEntitlement = purchaserInfo.entitlements.active.values
.map((e) => e.identifier)
.join(', ');

print('Active subscription status: $_hasActiveSubscription');
print('Active entitlements: $_activeEntitlement');

notifyListeners(); // Notify listeners about all changes
saveSubscriptionStatusToSharedPreferences();
}




Future<bool> restorePurchases() async {
print('Attempting to restore purchases...');
try {
CustomerInfo restoredCustomerInfo = await Purchases.restorePurchases();
print('Purchases restored. Info: $restoredCustomerInfo');
updateSubscriptionStatus(restoredCustomerInfo);
return true;
} catch (e) {
print('Failed to restore purchases: $e');
return false;
}
}



}

 

Hi,

Unfortunately that isn’t possible, as we generate those at random. You could store the initial anonymous id and use it to configure/login the SDK (however, then you’re back to storing user ids).

I would recommend storing the user ids, and I know some of our customers like Firebase/Supabase for that.