Identity: anonymous and signed-in users

Identity is carried by AppwinCore, not by the products. One device, one session, one user: the Community, Support and Notifications modules all read the same one. That is what makes a person identified in your app the same interlocutor everywhere, with nothing for you to copy from one product to another.

Three states, in this order. Each is usable on its own: you can stop at the first and have a working integration.

1. Anonymous - nothing to do

From configure on, the SDK recognises the device: it generates an identifier, persists it, and opens an authenticated session in the background. The end-user can read and write with no sign-up.

swift
AppwinCore.configure(projectAppId: "your-app-id")
print(AppwinCore.deviceId ?? "-")   // stable from one launch to the next

The identifier is persisted in the keychain, so it survives an uninstall. That is what stops a person losing their history when they change app version.

What this end-user sees depends on the product. In Community, their profile is born with a stable generated nickname ("Curious Otter 417"), derived from their identifier: if they reinstall the app they get the same nickname back rather than a new identity in other people's eyes. In Support, they open a conversation as a visitor.

An anonymous member can name themselves from the SDK's profile screen. They do not need you for that.

2. Signed in - attaching to your user

When your app knows who the person is, push your identifier, the one from your database. Appwin does not interpret it: it serves to recognise the same person from one device to another and from one product to another.

swift
try await AppwinCore.identify(
  externalId: user.id,
  attributes: AppwinUserAttributes(email: user.email, name: user.name)
)

Call it once, at sign-in. The SDK stores the externalId on the device and reuses it on every launch: there is nothing to call again at the next start. attributes is optional; you can also push them later with updateUser.

identify is the only way in: Support, Community and Notifications have no login function of their own. They are notified by Core and pick up the new person by themselves.

This is where the sharing happens: after that attachment, this person is the same one for Support and for Community. Their conversations and their profile belong to the same individual, and your team sees a single interlocutor. The anonymous history of the device (conversations started before sign-in, for instance) is merged into that person.

Signing out

swift
await AppwinCore.logout()

logout revokes the session on the server, forgets the stored externalId and goes back to an anonymous profile, and the device's push token is registered on that new session. Call it when the user signs out of your app - otherwise the next person on the same device would inherit their identity.

3. Enriched - pushing attributes

Your app often already knows a name, a picture, an email, a plan. Pushing them saves the person some typing and lets you target them. There are two bridges, because the attributes are not the same: a community profile is not a customer record.

Carried byMethodFields
Core (the customer, shared by every product)AppwinCore.updateUser(...)email, name, avatarUrl, language, timezone, location, plan
Community (the public profile)AppwinCommunity.setUser(...)nickname, avatarUrl, bio
swift
try await AppwinCore.updateUser(AppwinUserAttributes(plan: "pro", language: "fr"))

try await AppwinCommunity.setUser(
  nickname: user.displayName,
  avatarUrl: user.photoURL?.absoluteString
)

Two rules:

  • Every field is optional. An omitted field is not overwritten: an app that only knows a plan does not erase the email, and an app that only knows a nickname does not erase the bio typed inside the SDK.
  • Providing a nickname takes the community profile out of anonymity. It is the act that gives a visible identity. The member can go back explicitly from their profile.

These methods do not change identity: they enrich the profile. To attach to your user, that is step 2.


When to call what

Plain text
App launch                → AppwinCore.configure(...)          always
Sign-in in YOUR app       → AppwinCore.identify(...)           once, persisted
A attribute changes           → AppwinCore.updateUser(...)         plan, language...
Community profile         → AppwinCommunity.setUser(...)       nickname, bio
Sign-out in YOUR app      → AppwinCore.logout()                back to anonymous

Pushing attributes before identify is not lost: they land on the anonymous profile, which is merged into the person at sign-in. Passing them to identify directly saves a call.

What is shared, and what is not

Carried by Core, sharedSpecific to each product
Device identifierCommunity profile (nickname, avatar, bio)
Session and tokenModeration sanctions
externalIdSupport conversations
Customer attributes (email, name, language, plan...)
Device metadata, push token and opt-in

Moderation

Three sanctions exist on the Community side, decided from the dashboard: a warning, a read-only ban, and a shadow ban - the member keeps posting and sees their own content, nobody else does, and they are never told, neither by the UI nor by an API response. The SDK is designed to leak nothing about it. The detail is in Driving Community.

Privacy

What the SDK sends, and nothing more:

  • a device identifier generated by the SDK - not the IDFA, not the IDFV, not the Android advertising ID
  • the platform, the model, the OS and app version
  • the device language, for content translation
  • the externalId you provide, if you provide one

The SDK reads neither the address book, nor the location, nor advertising identifiers. Since the externalId is chosen by you, you can put an opaque identifier in it rather than an email if you prefer.

Next

  • Installation - dependencies, initialisation, environment
  • Community - showing the feed and customising it