Duplicate Display Screenshot Firestore Queries Screenshot
I am using Jetpack Compose + HiltViewModel + Firestore database
When I perform add action somehow the last entry is duplicated on LazyColumn.
The data is added correctly to the Firestore database [9604], but somehow the display is totally wrong [showing 2804 twice] until I restart the emulator or I rotate the device.
Below are the code that I think might be relevant.
@OptIn(ExperimentalLifecycleComposeApi::class)
@Composable
fun PatientsScreen(
modifier: Modifier = Modifier,
viewModel: PatientsViewModel = hiltViewModel()
) {
val patients = viewModel.patients.collectAsStateWithLifecycle(emptyList())
Column {
LazyColumn {
items(patients.value) { patientItem ->
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween
) {
Text(patientItem.pid, fontSize = 24.sp)
Text(patientItem.location, fontSize = 24.sp)
Button(
onClick = { viewModel.onAcknowledge(patient = patientItem) },
enabled = patientItem.status.equals("Activated"),
shape = RoundedCornerShape(30)
) {
if (patientItem.status.equals("Activated")) {
Text("Acknowledge")
} else {
Text(patientItem.status)
}
}
}
}
}
Button(
onClick = { viewModel.registerPatient() },
shape = CircleShape
)
{
Text("+", fontSize = 36.sp)
}
}
}
@HiltViewModel
class PatientsViewModel @Inject constructor (
private val storageService: StorageService,
) : ViewModel() {
val patients = storageService.patients
fun onAcknowledge(patient: Patient) {
viewModelScope.launch {
storageService.update(patient.copy(status = "Acknowledged"))
}
}
fun registerPatient() {
val patient = mutableStateOf(Patient())
val newId = Random.nextInt(0, 9999).toString().padStart(4, '0')
patient.value = patient.value.copy(pid = newId)
patient.value = patient.value.copy(status = "Unused")
viewModelScope.launch {
val newPatient = patient.value
storageService.add(newPatient)
}
}
}
class StorageServiceImpl
@Inject
constructor(private val firestore: FirebaseFirestore) : StorageService {
override val patients: Flow<List<Patient>>
get() =
currentCollection().snapshots().map { snap ->
snap.toObjects()
}
override suspend fun getPatient(patientId: String): Patient? =
currentCollection().document(patientId).get().await().toObject()
override suspend fun add(patient: Patient): String =
currentCollection().add(patient).await().id
override suspend fun update(patient: Patient) {
currentCollection().document(patient.id).set(patient).await()
}
override suspend fun delete(patientId: String) {
currentCollection().document(patientId).delete().await()
}
private fun currentCollection(): CollectionReference =
firestore.collection(PATIENT_COLLECTION)
companion object {
private const val PATIENT_COLLECTION = "patients"
}
}
The LazyColumn displaying the new entry registerPatient()