Authentication
The Authentication module manages sign-in, account creation, token storage, and logout. After a successful sign-in, AFCore stores the session securely and attaches authentication tokens to all subsequent API requests.
How It Works
- Your app calls
signInOrCreateMemberwith an external user identifier (from your SSO, SAML, or custom identity provider). - If the member exists, AFCore signs them in. If not, it creates the member and signs them in automatically.
- AFCore stores the access and refresh tokens in platform-secure storage (Android EncryptedSharedPreferences / iOS Keychain).
- All subsequent SDK calls include the token automatically -- no manual header management required.
Sign In or Create a Member
Use signInOrCreateMember to authenticate using an external identity. Optional profile fields seed the member's profile on first creation.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
externalUserId | String | Yes | Unique identifier from your identity provider. |
email | String? | No | Member's email address. |
firstName | String? | No | Given name. |
middleName | String? | No | Middle name. |
lastName | String? | No | Family name. |
gender | String? | No | "M" or "F". |
dateOfBirth | String? | No | ISO-8601 format (YYYY-MM-DD). |
phoneNumber | String? | No | Contact number. |
address1 | String? | No | Primary street address. |
address2 | String? | No | Secondary address line. |
city | String? | No | City. |
state | String? | No | Two-letter state code. |
zip | String? | No | Postal code. |
attributes | Map<String, String?>? | No | Freeform key-value pairs for custom profile data. |
Returns
AFResult -- check result.status (Boolean) for success and result.statusMessage for details on failure.
- Android (Kotlin)
- iOS (Swift)
lifecycleScope.launch {
try {
val result = AFCore.authentication().signInOrCreateMember(
externalUserId = "sso-user-98765",
email = "alex@example.com",
firstName = "Alex",
lastName = "Rivera",
dateOfBirth = "1988-07-12",
attributes = mapOf("groupId" to "GR-2504")
)
if (result.status) {
// Session is active. Navigate to the main screen.
navigateToHome()
} else {
// The server rejected the request. Show the reason.
showError("Sign-in failed: ${result.statusMessage}")
}
} catch (e: Exception) {
// Network or unexpected error.
showError("Could not connect: ${e.message}")
}
}
do {
let result = try await AFCore.shared.authentication().signInOrCreateMember(
externalUserId: "sso-user-98765",
email: "alex@example.com",
firstName: "Alex",
lastName: "Rivera",
dateOfBirth: "1988-07-12",
attributes: ["groupId": "GR-2504"]
)
if result.status {
navigateToHome()
} else {
showError("Sign-in failed: \(result.statusMessage ?? "Unknown error")")
}
} catch {
showError("Could not connect: \(error)")
}
Logout
logout() clears all stored tokens and local SDK state for the current member. Call this when the user explicitly signs out.
- Android (Kotlin)
- iOS (Swift)
lifecycleScope.launch {
val result = AFCore.authentication().logout()
if (result.status) {
// Tokens cleared. Return to the login screen.
navigateToSignIn()
}
}
let result = try await AFCore.shared.authentication().logout()
if result.status {
navigateToSignIn()
}
After logout, stop any active geofence monitoring and cancel background sync tasks. The member must sign in again before making any further SDK calls.
Best Practices
- Call sign-in once per session. AFCore handles token refresh automatically. You do not need to re-authenticate on every app launch -- the stored session persists across launches.
- Pass profile fields on first sign-in. Optional parameters like
firstName,email, anddateOfBirthseed the server-side profile. If the member already exists, these fields are ignored unless the server is configured to update them. - Handle token expiry gracefully. If a token refresh fails (for example, after extended offline periods), AFCore throws an exception on the next API call. Catch it and redirect to sign-in.
- Secure the external user ID. The
externalUserIdis the bridge between your identity system and AFCore. Validate it server-side if possible.
Error Handling
| Scenario | Recommended Action |
|---|---|
result.status == false | Display result.statusMessage to the user. Common causes: invalid credentials, disabled account, or server maintenance. |
| Network exception | Show a retry option. AFCore does not retry authentication automatically. |
| Token refresh failure | Redirect to sign-in. The session has expired. |
Quick Reference
- Android (Kotlin)
- iOS (Swift)
// Android
AFCore.authentication().signInOrCreateMember(externalUserId = "id", ...)
AFCore.authentication().logout()
// iOS
try await AFCore.shared.authentication().signInOrCreateMember(externalUserId: "id", ...)
try await AFCore.shared.authentication().logout()