This guide covers authentication management and user state tracking in the Virtual Stadium Data SDK.
The LoginManager handles login operations within the Virtual Stadium Data SDK. It provides functionalities to perform user authentication through JWT token validation and manage user sessions.
The LoginManager plays a crucial role in ensuring that users are authenticated before they can interact with the SDK's features. It uses JWT tokens, which are compact and secure, for authenticating users.
login(jwtToken: String)
Authenticates the user with the provided JWT token. This is a prerequisite for all SDK interactions.
logOut()
Performs the logout operation, ending the user's session.
loginState
Observable flow for tracking authentication status changes.
Inject LoginManager via dependency injection and expose the loginState flow to your UI layer.
Monitor login state to handle different authentication statuses:
import ag.sportradar.virtualstadium.datasdk.services.LoginManager
import androidx.lifecycle.ViewModel
import org.koin.core.component.KoinComponent
import org.koin.core.component.get
class LoginViewModel :
ViewModel(),
KoinComponent {
private val loginManager: LoginManager
get() = get()
val loginState = loginManager.loginState
fun login(jwtToken: String) {
loginManager.login(jwtToken)
}
fun logout() {
loginManager.logOut()
}
}Implement a login screen that responds to authentication state changes.
Handle all login states appropriately:
Jetpack Compose:
@Composable
fun LoginScreen(
modifier: Modifier = Modifier,
loginViewModel: LoginViewModel,
) {
val loginState by loginViewModel.loginState
.collectAsStateWithLifecycle()
Scaffold { paddingValues ->
when (loginState.loginStatus) {
LoginStatus.LOGGED_OUT -> {
Box(
modifier = Modifier
.padding(paddingValues)
.fillMaxSize(),
contentAlignment = Alignment.BottomCenter,
) {
OutlinedButton(
onClick = {
loginViewModel.login("YOUR_JWT_TOKEN")
},
) {
Text("Log In")
}
}
}
LoginStatus.LOADING -> {
Box(
modifier = Modifier
.padding(paddingValues)
.fillMaxSize(),
contentAlignment = Alignment.Center,
) {
CircularProgressIndicator()
}
}
LoginStatus.LOGGED_IN -> {
ExampleScreen(loginViewModel = loginViewModel)
}
LoginStatus.ERROR -> {
Column(
modifier = Modifier
.padding(paddingValues)
.fillMaxSize(),
verticalArrangement = Arrangement.Center,
) {
Text("Error: ${loginState.loginError?.message}")
OutlinedButton(
onClick = {
loginViewModel.login("YOUR_JWT_TOKEN")
},
) {
Text("Try to log in again")
}
}
}
}
}
}The UserProvider is a crucial component designed to manage and maintain user-related data and state. It encapsulates functionalities essential for handling user data, managing user states, and dealing with user infractions within the application.
The UserProvider ensures that user-related operations are performed in a secure, efficient, and consistent manner, maintaining the integrity of the user experience.
To detect state changes of the current user's status, collect changes from the SDK's UserProvider. The UserState class contains values for the user and their status.
UserStatus.Initial
Initial status value before user state is determined.
UserStatus.Valid
User can post messages normally.
UserStatus.Timeout(remainingSeconds)
User is temporarily banned. The remainingSeconds value updates every second.
UserStatus.Banned
User is permanently banned and cannot post messages.
Access user state and infraction management through the UserProvider.
The provider exposes:
Methods for infraction management:
class LoginViewModel :
ViewModel(),
KoinComponent {
private val userProvider: UserProvider
get() = get()
// Represents the current state of the user
val userState = userProvider.userState
// Indicates which is the next infraction for the user
val nextInfraction = userProvider.nextInfraction
// Countdown timer for dismissing the infraction
val dismissInfraction = userProvider.dismissTimerCountDown
fun startDismissInfractionJob() {
userProvider.startAutoDismissInfraction()
}
fun stopDismissInfractionJob() {
userProvider.stopAutoDismissInfraction()
}
fun getNextInfraction() {
userProvider.getNextInfraction()
}
fun removeFirstInfraction() {
userProvider.removeFirstInfraction()
}
}All state variables are of type CommonStateFlow, which can be collected (Android) or subscribed to (iOS), similar to loginState in the Login Screen Example.