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.
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.
AppwinCore.identify(externalId: user.id)
try await AppwinCore.bootstrapSession(externalId: user.id)
Two moves rather than one: identify records the externalId in the local
identity, bootstrapSession(externalId:) mints a token that carries it. Without
the second, the open session stays the anonymous profile's until the app next
starts.
The product modules expose a shortcut - AppwinCommunity.login(...),
AppwinSupport.loginIdentifiedUser(...) - which pushes the same value into Core
and attaches the person on the server side. It is the default path on React
Native, where Core does not expose the externalId variant.
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.
Signing out
await AppwinCore.signOut()
signOut revokes the session on the server, clears local storage and goes back
to an anonymous profile. Call it when the user signs out of your app -
otherwise the next person on the same device would inherit their identity.
There is also clearIdentity(), which forgets the externalId locally without
revoking anything. It is a testing tool, not a sign-out.
3. Enriched - pushing attributes
Your app often already knows a nickname, a picture, an email. Pushing them saves the person some typing. This bridge is specific to each product, because the attributes are not the same: a community profile is not a customer record.
| Product | Method | Fields |
|---|---|---|
| Community | AppwinCommunity.setUser(...) | nickname, avatarUrl, bio |
| Support | AppwinSupport.updateUser(...) | name, email, avatarUrl, language, timezone, location |
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 nickname does not erase the bio typed inside the SDK.
- Providing a
nicknametakes 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
App launch → AppwinCore.configure(...) always
Sign-in in YOUR app → identify + bootstrapSession attachment
(or the product's login)
Right after → setUser / updateUser attributes
Profile changed on your → setUser / updateUser update
side
Sign-out in YOUR app → AppwinCore.signOut() back to anonymous
Order matters: the attachment before the attributes. Pushed the other way round, they land on the anonymous profile and are lost when it is attached.
What is shared, and what is not
| Carried by Core, shared | Specific to each product |
|---|---|
| Device identifier | Community profile (nickname, avatar, bio) |
| Session and token | Support customer record (email, language, plan) |
externalId | Moderation sanctions |
| 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
externalIdyou 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