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
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

swift
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.

ProductMethodFields
CommunityAppwinCommunity.setUser(...)nickname, avatarUrl, bio
SupportAppwinSupport.updateUser(...)name, email, avatarUrl, language, timezone, location
swift
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 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       → 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, sharedSpecific to each product
Device identifierCommunity profile (nickname, avatar, bio)
Session and tokenSupport customer record (email, language, plan)
externalIdModeration sanctions
Device metadataPush 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