RevenueCat provides a source of truth for a subscriber's status across different platforms. To do this, each subscriber has an App User ID that uniquely identifies them within your application.
User identity is one of the most important components of many mobile applications, and it's extra important to make sure the subscription status RevenueCat is tracking gets associated with the correct user.
The Purchases SDK allows you to specify your own user identifiers or use anonymous identifiers generated by RevenueCat. Some apps will use a combination of their own identifiers and RevenueCat anonymous Ids - that's okay!
Anonymous App User Ids
If you don't provide an App User ID when instantiating the Purchases SDK, RevenueCat will create a new random App User ID for you and cache it on the device. In the event that the user deletes and reinstalls the app, a new random App User ID will be generated.
Purchases.configure(withAPIKey: "my_api_key")
[RCPurchases configureWithAPIKey:@"my_api_key"];
Purchases.configure(this, "my_api_key")
Purchases.configure(this, "my_api_key");
await Purchases.setup("public_sdk_key");
Purchases.setup("public_sdk_key");
Purchases.setup("public_sdk_key");
See Unity installation instructions https://docs.revenuecat.com/docs/unity
Anonymous App User Ids are always prefixed with
$RCAnonymousID:
for SDK versions 3+. This can be useful for working with anonymous users on your server.
Provided App User ID
Setting your own App User ID will allow you to reference users in the RevenueCat dashboard, via the API, as well as in the webhooks and other integrations.
Using an externally managed App User ID also provides a mechanism by which to restore purchases in a few scenarios:
- When a user deletes and reinstalls your app - using the same App User ID will ensure they still have access to subscriptions previously started without requiring a restore.
- When the user logs in on multiple devices - you can honor a subscription that was purchased on one device across any other platform.
Set App User ID on configuration
If you have your own App User IDs, you can pass those on instantiation to Purchases.
Purchases.configure(withAPIKey: "my_api_key", appUserID: "my_app_user_id")
[RCPurchases configureWithAPIKey:@"my_api_key" appUserID:@"my_app_user_id"];
Purchases.configure(this, "my_api_key", "my_app_user_id")
Purchases.configure(this, "my_api_key", "my_app_user_id");
await Purchases.setup("public_sdk_key", appUserId: "my_app_user_id");
Purchases.setup("public_sdk_key", "my_app_user_id");
Purchases.setup("public_sdk_key", "my_app_user_id");
See Unity installation instructions https://docs.revenuecat.com/docs/unity
Set App User ID after configuration
If your app doesn't receive its own App User ID until later in its lifecycle, you can set (or change) the App User ID at any time by calling .identify()
. The most common cases are users creating accounts or logging in.
// Configure Purchases on app launch
Purchases.configure(withAPIKey: "my_api_key")
//...
// Later log in provided user Id
Purchases.shared.identify("my_app_user_id") { (purchaserInfo, error) in
// purchaserInfo updated for my_app_user_id
}
// Configure Purchases on app launch
[RCPurchases configureWithAPIKey:@"my_api_key"];
//...
// Later log in provided user Id
[[RCPurchases sharedPurchases] identify:@"my_app_user_id" completionBlock:^(RCPurchaserInfo *purchaserInfo, NSError *error) {
// purchaserInfo updated for my_app_user_id
}];
// Configure Purchases on app launch
Purchases.configure(this, "my_api_key")
//...
// Later log in provided user Id
Purchases.sharedInstance.identifyWith("my_app_user_id", ::showError) { purchaserInfo ->
// purchaserInfo updated for my_app_user_id
}
// Configure Purchases on app launch
Purchases.configure(this, "my_api_key");
//...
// Later log in provided user Id
Purchases.sharedInstance.identifyWith("my_app_user_id", ::showError) { purchaserInfo ->
// purchaserInfo updated for my_app_user_id
}
Purchases.getSharedInstance().identify("my_app_user_id", new ReceivePurchaserInfoListener() {
@Override
public void onReceived(@android.support.annotation.Nullable PurchaserInfo purchaserInfo, @android.support.annotation.Nullable PurchasesError error) {
// purchaserInfo updated for my_app_user_id
}
});
// Configure Purchases on app launch
await Purchases.setup("public_sdk_key");
//...
// Later log in provided user Id
PurchaserInfo purchaserInfo = await Purchases.identify("my_app_user_id");
// Configure Purchases on app launch
Purchases.setup("public_sdk_key");
//...
// Later log in provided user Id
const purchaserInfo = await Purchases.identify("my_app_user_id");
// purchaserInfo updated for my_app_user_id
// Configure Purchases on app launch
Purchases.setup("public_sdk_key");
//...
// Later log in provided user Id
Purchases.identify(
"my_app_user_id",
info => {
// purchaserInfo updated for my_app_user_id
},
error => {
}
);
purchases.Identify("my_app_user_id", (purchaserInfo, error) => {
// purchaserInfo updated for my_app_user_id
});
If Purchases is initialized with an Anonymous App User ID, then later identified with a Provided App User ID, the users will automatically be aliased together and treated as the same record in RevenueCat.
Aliasing
Aliasing is when two App User Ids get merged together and treated as the same user in RevenueCat - effectively connecting two sets of user data as one. The user can then be referenced by any of their aliases and the same result will be returned.
Aliases are needed to effectively manage identify between RevenueCat and the app stores. Since a subscription is ultimately linked to an Apple/Google account, and the stores don't provide any unique user identifier themselves, there are cases when the same store receipt needs to be associated with multiple App User Ids in RevenueCat.
You can expect aliases for the following cases:
- Two different App User Ids restore the same purchase receipt
- An Anonymous App User ID gets merged with a provided App User Id through
.identify()
Logging Out
When a user logs out you should call the reset()
method - this a new Anonymous App User Id for the logged out state.
Logging back in
To log in a new user, the provided App User Id should be set again with .identify()
.
Sharing Subscriptions Across Platforms
You can share a subscription across platforms (e.g. iOS -> Android) by identifying with the same App User ID. This is usually done through your own authentication mechanism.
Note that a user can only manage their subscription on the platform it was purchased from.
Tips for setting App User IDs
App User IDs Should Not Be Guessable
RevenueCat provides subscription status via the public API, having App User IDs that are easily guessed is not good. It is recommended to use a non-guessable psuedo-random ID that isn't made public inside your app.
Don't set emails as App User IDs
For the above reason, and GDPR compliance, we don't recommend using email addresses as App User IDs
Don't set IDFA as App User IDs
Advertising identifiers should not be used as App User IDs since they can be easily rotated and are not unique across users if limit ad tracking is enabled.
Don't hardcode strings as App User IDs
You should never hardcode a string as an App User ID, since every install will be treated as the same user in RevenueCat. This will create problems and could unlock entitlements for users that haven't actually purchased.
Every app user ID must be unique per user. If you don't have your own user IDs for some of your users, you should pass null for the App User ID on configuration which will rely on the anonymous IDs created by RevenueCat.
Keep App User IDs shorter than 100 characters
App User IDs should not be longer than 100 characters.
Blocked App User IDs
Certain App User Ids are blocked in RevenueCat. This is by design to help developers that may be unintentionally passing non-unique strings as user identifiers. The current block-list is:
no_user
, null
, none
, nil
, (null)
, ``(empty string).
Next Steps
- Enrich your app by reacting to the user's current subscription status
- If you're moving to RevenueCat from another system, see our guide on migrating your existing subscriptions
- Once you're ready to test your integration, you can follow our guides on testing and debugging
Updated 2 months ago