The inability to retrieve the correct user ID, which prevents me from assigning a note to the logged-in user.
Hey, for the past two weeks, I've been struggling with an issue while creating a login-enabled note-taking application in Android Studio using Jetpack Compose and Room Database. I just started learning and this problem makes me crazy because i know someone with experience would fix this probably in 5 minutes.
First and foremost, I'd like to mention that I found a similar problem on a forum text, but the solution provided didn't work in my case, I even tried to ask ChatGPT for help and that's still not working.
Below, I'm providing the code for LoginRegisterViewModel, NotesViewModel, and the CreateNote Composable function where I invoke the logged-in user. Sorry for a mess in code but that's a "last version" of my code when i was trying to repair this :/
LoginRegisterViewModel:
class LoginRegisterViewModel(app: Application) : AndroidViewModel(app) {
private val repo = UserRepository(app.applicationContext)
private var userExist = false
private val currentUser = MutableStateFlow<User?>(null)
private var userId : Int? = null
suspend fun checkPassword(username: String, password: String): Boolean {
return withContext(Dispatchers.IO) {
val user = getUserByLoginAndPassword(username, password)
user != null
}
}
fun getUserId(): Int? {
println(userId)
return userId
}
private fun setCurrentUser(user: User) {
currentUser.value = user
userId = user.id
}
suspend fun checkIfUserExists(loginValue: String): Boolean {
return withContext(Dispatchers.IO) {
val user = repo.getUserByLogin(loginValue)
user != null
}
}
private suspend fun getUserByLoginAndPassword(
loginValue: String,
passwordValue: String
): User? {
return repo.getUserByLoginAndPassword(loginValue, passwordValue)
}
suspend fun login(loginValue: String, passwordValue: String): Boolean {
return withContext(Dispatchers.IO) {
val user = getUserByLoginAndPassword(loginValue, passwordValue)
if (user != null) {
setCurrentUser(user)
userId = repo.getUserId(loginValue)
println(currentUser.value)
true
} else {
false
}
}
}
fun logout() {
currentUser.value = null
}
fun registerUser(
nameValue: String,
loginValue: String,
passwordValue: String,
confirmPasswordValue: String
) {
viewModelScope.launch(Dispatchers.IO) {
if (passwordValue == confirmPasswordValue) {
userExist = false
val user = User(
nameValue = nameValue,
loginValue = loginValue,
passwordValue = passwordValue
)
repo.insert(user)
} else {
userExist = true
}
}
}
}
NotesViewModel:
class NotesViewModel(
private val repo: NotesRepository, private val userId: Int?
) : ViewModel() {
val getNotesByUserId: List<Note> = runBlocking { repo.getNotesByUserId(userId) }
fun deleteNotes(note: Note) {
viewModelScope.launch(Dispatchers.IO) {
repo.deleteNote(note)
}
}
fun updateNote(note: Note) {
viewModelScope.launch(Dispatchers.IO) {
repo.updateNote(note)
}
}
fun createNote(title: String, note: String, userId: Int?) {
viewModelScope.launch(Dispatchers.IO) {
repo.insertNote(Note(title = title, note = note, userId = userId))
println(userId)
}
}
suspend fun getNote(noteId: Int): Note? {
return repo.getNoteById(noteId)
}
}
@Suppress("UNCHECKED_CAST")
class NotesViewModelFactory(
private val repo: NotesRepository, private val loginRegisterViewModel: LoginRegisterViewModel
) : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return NotesViewModel(repo, loginRegisterViewModel.getUserId()) as T
}
}
CreateNote Composable function:
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter", "UnusedMaterialScaffoldPaddingParameter")
@Composable
fun CreateNote(
navController: NavController,
viewModel: NotesViewModel,
userId: Int?
) {
val currentNote = remember {
mutableStateOf("")
}
val currentTitle = remember {
mutableStateOf("")
}
val saveButtonState = remember {
mutableStateOf(false)
}
val currentUser = remember {
mutableStateOf(userId)
}
println(currentUser)
NotepadTheme {
Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colors.background) {
Scaffold(
topBar = {
AppBar(
title = "Create Note",
onIconClick = {
viewModel.createNote(
currentTitle.value,
currentNote.value,
currentUser.value
)
navController.popBackStack()
},
icon = {
Icon(
imageVector = ImageVector.vectorResource(R.drawable.save),
contentDescription = stringResource(R.string.save_note),
tint = Color.Black,
)
},
iconState = remember { mutableStateOf(true) }
)
},
) {
Column(
Modifier
.padding(12.dp)
.fillMaxSize()
) {
TextField(
value = currentTitle.value,
modifier = Modifier.fillMaxWidth(),
onValueChange = { value ->
currentTitle.value = value
saveButtonState.value =
currentTitle.value != "" && currentNote.value != ""
},
colors = TextFieldDefaults.textFieldColors(
cursorColor = Color.Black,
focusedLabelColor = Color.Black
),
label = { Text(text = "Title") }
)
Spacer(modifier = Modifier.padding(12.dp))
TextField(
value = currentNote.value,
modifier = Modifier
.fillMaxHeight(0.5f)
.fillMaxWidth(),
onValueChange = { value ->
currentNote.value = value
saveButtonState.value =
currentTitle.value != "" && currentNote.value != ""
},
colors = TextFieldDefaults.textFieldColors(
cursorColor = Color.Black,
focusedLabelColor = Color.Black
),
label = { Text(text = "Note") }
)
}
}
}
}
}
Thanks in advance for any kind of help!