Identity¶
IdentifiableUserService tells every vendor who the user is at sign-in, so what's collected from
then on belongs to that user, and forgets them at sign-out.
class AnalyticsIdentity(private val identity: IdentifiableUserService) {
suspend fun onSignedIn(userId: String) = identity.identify(Identity(userId))
suspend fun onSignedOut() = identity.reset()
/** At every cold start: some vendors do not remember the user between launches. */
suspend fun restore(session: Session) {
session.userId?.let { identity.identify(Identity(it)) }
}
}
final class AnalyticsIdentity {
private let identity: any IdentifiableUserService
init(identity: any IdentifiableUserService) {
self.identity = identity
}
func onSignedIn(userId: String) {
identity.identify(Identity(userId: userId))
}
func onSignedOut() {
identity.reset()
}
/// Call it at every app start: some vendors forget the user between launches.
func restore(session: any Session) {
if let userId = session.userId {
identity.identify(Identity(userId: userId))
}
}
}
class AnalyticsIdentity(final IdentifiableUserService identity) {
Future<void> onSignedIn(String userId) => identity.identify(Identity(userId));
Future<void> onSignedOut() => identity.reset();
/// Call it at every app start: some vendors forget the user between launches.
Future<void> restore(Session session) async {
if (session.userId case final userId?) await identity.identify(Identity(userId));
}
}
export class AnalyticsIdentity {
constructor(private readonly identity: IdentifiableUserService) {}
onSignedIn(userId: string): Promise<void> {
return this.identity.identify(new Identity(userId));
}
onSignedOut(): Promise<void> {
return this.identity.reset();
}
/** Call it at every app start: some vendors forget the user between launches. */
async restore(session: Session): Promise<void> {
if (session.userId !== undefined) await this.identity.identify(new Identity(session.userId));
}
}
Identity.userId uses the name every vendor uses. Pass an id that doesn't change and doesn't
reveal who the person is, such as your backend's account id, never an email address or a phone
number.
What each vendor does¶
| Vendor | identify |
reset |
|---|---|---|
| Firebase | setUserId(userId) |
setUserId(null) |
| Mixpanel | identify(userId, true) |
reset(): a new anonymous id |
| Adjust | a user_id global callback parameter; the key is configurable |
removes that parameter |
| AppsFlyer | setCustomerUserId(userId) |
setCustomerUserId(null); nothing on Flutter and React Native, whose packages can't clear it |
| Amplitude | setUserId(userId) |
reset(): clears the user and rotates the device id |
If your app must not send a user id to a vendor, register that vendor's provider without
identity.
Every cold start¶
Not every vendor remembers the user. AppsFlyer 7 forgets the user id between launches, so a
signed-in user who reopens the app would be anonymous there. At every start-up, identify a
signed-in user again, as restore above does.
The order matters for AppsFlyer. It attaches the user id to the launch it sends when it starts, and with Herald that happens when consent is re-applied. So identify the user before re-applying consent:
start()identify(...), if a user is signed insetEnabled(storedDecision)