Accounts, Login, and Logout

If you create user accounts for your app users, we describe in this guide how to integrate this information with Nami.

If your app allows users to register, create an account or sign-in to an existing account, sharing this context with Nami unlocks two benefits:

  1. Enables the user to share access to entitlements across devices or even platforms that were granted by the paid purchase of a subscription or IAP
  2. Enables Nami to enrich data we provide you through analytics, web hooks, and APIs with a unique identifier you can use to identify the user

In order to take advantage of this mechanism, you need to provide Nami a known user identifier for a user's account. We refer to this identifier as the external identifier.

Uniquely identifying accounts with an External Identifier

Nami provides a simple call to associate a device with an external identifier that you can use to identify register user.

An example call to NamiCustomerManager.login using a UUID external identifier looks like:

NamiCustomerManager.login(withId: "035b30e2-faf4-462d-aec3-caa0fbe26c49")
NamiCustomerManager.login(withId: "035b30e2-faf4-462d-aec3-caa0fbe26c49")
NamiCustomerManager.login("035b30e2-faf4-462d-aec3-caa0fbe26c49");

There are two important things to know about external identifiers.

Nami only accepts two types for external identifiers:

  • SHA256
  • UUID
  • Numeric

If you wish to use a piece of data on your side that is more descriptive, such as an email address or a username, we recommend computing the SHA256 for that descriptor and using the result when your call our SDK.

Nami can also only store a single external identifier for a customer.

If a user signs out or switches accounts, you can clear a previously set identifier by calling NamiCustomerManager.logout:

NamiCustomerManager.logout()
NamiCustomerManager.logout()
NamiCustomerManager.logout();

To keep track of account state changes, you can register to receive a callback with NamiCustomerManager.registerAccountStateHandler whenever login or logout returns with status of whether the action was successful:

NamiCustomerManager.registerAccountStateHandler { accountStateAction, success, error in
     if success {
         if accountStateAction == .login {
           // logged in
         } else if accountStateAction == .logout {
           // logged out
         }        
     } else {
       // an error occured
     }
}
NamiCustomerManager.registerAccountStateHandler { accountStateAction, success, error ->
    if (success) {
        if (accountStateAction == AccountStateAction.LOGIN) {
            Log.d(LOG_TAG, "User is logged in")
        } else if (accountStateAction == AccountStateAction.LOGOUT) {
            Log.d(LOG_TAG, "User is logged out")
        }
    } else if (error != null) {
        if (accountStateAction == AccountStateAction.LOGIN) {
            Log.d(LOG_TAG, "There was an error logging in. Error - ${error}")
        } else if (accountStateAction == AccountStateAction.LOGOUT) {
            Log.d(LOG_TAG, "There was an error logging out. Error - ${error}")
        }
    }
}
NamiCustomerManager.registerAccountStateHandler()
    .listen((accountState) {
  print("AccountStateHandler triggered");

  if (accountState.success) {
    if (accountState.accountStateAction == AccountStateAction.login) {
      print("Login success");
    } else
    if (accountState.accountStateAction == AccountStateAction.logout) {
      print("Logout success");
    }
  } else {
    if (accountState.accountStateAction == AccountStateAction.login) {
      print("Login error - ${accountState.error}");
    } else
    if (accountState.accountStateAction == AccountStateAction.logout) {
      print("Logout error - ${accountState.error}");
    }
  }
});

You can ask if the device is currently associated with an external identifier by calling NamiCustomerManager.isLoggedIn.

Finally, you can query the SDK for the currently associated external identifier, if set, with NamiCustomerManager.loggedInId.

Sharing entitlements across platforms & devices

Access to one or more entitlements can be granted across devices and platforms as long as the device is logged in using an External Identifier.

For example, this makes it easy for a user who bought your subscription on an Apple device, to use it on an Android device

For this to work, each of the user's devices must be associated with the same External Identifier.

Best Practices for Implementation

We recommend adding the code described above to your app where the following scenarios occur.

ScenarioNami SDK Calls
User registers a new account1. Call login with an external identifier for the new account
User signs in
or
Signed in user's authorization token from your authentication service is refreshed.
1. Call isLoggedIn to check if Nami knows the user is logged in
2. If isLoggedIn is false, call login
3. If isLoggedIn is true, you can also check if loggedInId matches the expected value.
Sign out1. Call logout

📘

In the sign out scenario, calling logout will also remove any entitlements from the device. Any previously granted entitlements will remain with the user account defined by the external identifier and will be able to be accessed again on a subsequent sign-in.

See Understanding Transferred Events and Accounts for more about what happens to entitlements related to login and logout actions.

Linking data from Nami to your systems

Nami produces a number of events to help manage both the state of your users and how they progress through the lifecycle of your subscription products which we can send to you via Enabling Webhooks or through one of our partners, like mParticle.

If you have provided us with an external identifier, it will be attached to all user.subscription.* and user.journey.* events we produce.

Read more about our events here.

Combating fraud and account sharing

Nami has built-in some protections to ensure that a user cannot simply sign-in to multiple accounts to share a single purchase with multiple different accounts.

On our platform, we create a single user or account object that is linked to the External Identifier that you set as described above.

An entitlement on our platform is always linked to a single user or customer account. If the user signs in with a different account and they have an active purchase, that entitlement will transfer from the old account to the new account.

The Nami platform is designed to ensure that a purchase made on-device will always activate the entitlement for the user and account currently tied to that device. In a case where that on-device purchase is transferred to a new user account, any other devices that are linked to the old user account will lose access to the entitlement.

We produce user.subscription.transferred.from and user.subscription.transferred.to events when this situation occurs so you can gain insight into when this happens, which you can receive via certain integrations as described above.