I have a project where there is a feature that will allow the user/admin to add a new document and contact in firestore, a edit feature and a delete feature.
this is the Firestore query ` data class FirefighterAdmin(val documentId: String, val contactNumber: String)
private fun getEmergencyPhoneNumber(finalMunicipalityForm: String): List { val db = Firebase.firestore val TAG = "EmergencyPhoneNumber"
Log.d(TAG, "Retrieving emergency phone numbers for municipality: $finalMunicipalityForm")
var firefighters = mutableListOf<FirefighterAdmin>()
db.collection("Emergency Contacts")
.document("$finalMunicipalityForm")
.collection("Firefighters")
.get()
.addOnSuccessListener { querySnapshot ->
Log.d(TAG, "Successfully retrieved query snapshot for firefighters")
for (document in querySnapshot.documents) {
Log.d(TAG, "Processing document: ${document.id}")
val documentId = document.id
val contactNumber = document.getString("contacts") ?: ""
Log.d(TAG, "Extracted contact number: $contactNumber")
firefighters.add(FirefighterAdmin(documentId, contactNumber))
}
Log.d(TAG, "Retrieved firefighters: $firefighters")
// Update the state variable with the retrieved firefighters
firefighters.let { updatedFirefighters ->
firefighters = updatedFirefighters
}
}
.addOnFailureListener { exception ->
Log.e(TAG, "Error retrieving emergency phone numbers: ${exception.message}", exception)
}
return firefighters
} `
and this is the my lazy column
` Box( modifier = Modifier .fillMaxWidth() .fillMaxHeight(.8f) .background(containerColor) // Set the background color as needed ) { var contactNumber = "" var documentId =""
LazyColumn(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp)
) {
item {
if (firefighters != null) {
for (firefighter in firefighters!!) {
contactNumber = firefighter.contactNumber
documentId = firefighter.documentId
val editedContactNumber =
remember { mutableStateOf(contactNumber) }
Spacer(modifier = Modifier.height(5.dp))
Column {
Text(
text = "$documentId",
color = Color.Black,
style = LocalTextStyle.current,
modifier = Modifier
.paddingFromBaseline(
10.dp,
0.dp
) // Adjust vertical spacing as needed
)
Row(
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.padding(5.dp),
horizontalArrangement = Arrangement.SpaceBetween
) {
var isEditing by remember { mutableStateOf(false) }
Box(
modifier = Modifier
.size(width = 150.dp, height = 40.dp)
.border(2.dp, Color.Black)
.background(Color.White),
contentAlignment = Alignment.Center
) {
if (isEditing) {
TextField(
value = if (isEditing) editedContactNumber.value else "", // Show editedContactNumber if editing, otherwise show an empty string
onValueChange = { newValue ->
// Check if the input is not empty and contains only numeric characters
if (newValue.isNotEmpty() && newValue.all { char -> char.isDigit() }) {
// Check if the length is less than or equal to 11 digits
if (newValue.length <= 11) {
editedContactNumber.value =
newValue
contactNumber =
editedContactNumber.value
} else {
Log.d(
"editedContactNumber",
"editedContactNumber: Number Input is not Valid "
)
}
} else {
Log.d(
"EditInput",
"Empty Field"
)
}
// You can provide feedback to the user or handle other cases as needed
},
textStyle = LocalTextStyle.current.copy(
color = Color.Black,
fontSize = 14.sp
),
keyboardOptions = KeyboardOptions.Default.copy(
keyboardType = KeyboardType.Number
),
)
} else {
Text(
text = editedContactNumber.value,
color = Color.Black,
style = LocalTextStyle.current
)
}
}
Icon(
imageVector = if (isEditing) Icons.Default.Check else Icons.Default.Edit,
contentDescription = null,
tint = Color.Black,
modifier = Modifier
.size(24.dp)
.align(Alignment.Bottom)
.padding(bottom = 1.dp)
.clickable {
isEditing = !isEditing
if (!isEditing) {
if (editedContactNumber.value.length == 11) {
// Update the contact number in Firestore
if (finalMunicipalityForm != null) {
val db =
Firebase.firestore
db
.collection("Emergency Contacts")
.document("$finalMunicipalityForm")
.collection("Firefighters")
.document(documentId)
.update(
"contacts",
editedContactNumber.value
)
.addOnSuccessListener {
Log.d(
"EditNumber",
"Number updated successfully : $editedContactNumber.value"
)
isEditing =
false
Toast.makeText(context, "Number Updated", Toast.LENGTH_SHORT).show()
}
.addOnFailureListener { e ->
Log.e(
"EditNumber",
"Error updating number",
e
)
}
} else {
Toast.makeText(context, "Please enter 11-digit only", Toast.LENGTH_SHORT).show()
}
} else {
// Display error message
errorState =
"Invalid phone number. Please enter a 11-digit number."
}
}
}
)
Icon(
imageVector = Icons.Default.Delete,
contentDescription = null,
tint = Color.Black,
modifier = Modifier
.size(24.dp)
.align(Alignment.Bottom)
.padding(bottom = 1.dp)
.clickable {
// Delete the contact number from Firestore
if (finalMunicipalityForm != null) {
val db = Firebase.firestore
db
.collection("Emergency Contacts")
.document("$finalMunicipalityForm")
.collection("Firefighters")
.document(documentId)
.delete()
.addOnSuccessListener {
Log.d(
"DeleteNumber",
"Number deleted successfully"
)
isEditing = false
Toast.makeText(context, "Number Deleted Successfully", Toast.LENGTH_SHORT).show()
}
.addOnFailureListener { e ->
Log.e(
"DeleteNumber",
"Error deleting number",
e
)
}
} else {
// context.showToast("Error")
}
}
)
Icon(
imageVector = Icons.Default.LocationOn,
contentDescription = null,
tint = Color.Black,
modifier = Modifier
.size(40.dp)
.clickable {
userLocation?.let { location ->
// Call a function to handle sending SMS with location and phone number
sendLocationSMS(
context = context,
location = location,
phoneNumber = contactNumber
)
} ?: run {
Log.w(
"Clickable",
"User location is null"
)
}
}
)
Spacer(modifier = Modifier.width(2.dp))
Icon(
imageVector = Icons.Default.Phone,
contentDescription = null,
tint = Color.Black,
modifier = Modifier
.size(40.dp)
.clickable {
// Launch the dialer here
val dialIntent = Intent(
Intent.ACTION_DIAL,
Uri.parse("tel:$contactNumber")
)
dialerLauncher.launch(dialIntent)
}
)
}
Spacer(
modifier = Modifier
.height(1.dp)
.fillMaxWidth()
.background(Color.Black)
)
Spacer(modifier = Modifier.height(5.dp))
}
}
} // here
Column {
val mutableNewDocumentId = remember { mutableStateOf("") }
val mutableNewContactNumber = remember { mutableStateOf("") }
Text(
text = "Document ID",
style = MaterialTheme.typography.labelSmall,
color = Color.Black,
modifier = Modifier.padding(horizontal = 10.dp)
)
TextField(
value = mutableNewDocumentId.value,
onValueChange = { newValue ->
mutableNewDocumentId.value = newValue
},
textStyle = LocalTextStyle.current.copy(
color = Color.Black,
fontSize = 8.sp
),
modifier = Modifier
.border(2.dp, Color.Black) // Add a border
.size(width = 150.dp, height = 40.dp)
)
Spacer(modifier = Modifier.height(10.dp))
Text(
text = "Contact Number",
style = MaterialTheme.typography.labelSmall,
color = Color.Black,
modifier = Modifier.padding(horizontal = 10.dp)
)
val pattern = Regex("[0-9]+")
TextField(
value = mutableNewContactNumber.value,
onValueChange = { newValue ->
if (newValue.length <= 11 && pattern.matches(newValue)) {
mutableNewContactNumber.value = newValue
}
},
keyboardOptions = KeyboardOptions.Default.copy(
keyboardType = KeyboardType.Number
),
textStyle = LocalTextStyle.current.copy(
color = Color.Black,
fontSize = 8.sp
),
modifier = Modifier
.border(2.dp, Color.Black) // Add a border
.size(width = 150.dp, height = 40.dp)
)
Button(
onClick = {
val pattern = Regex("[0-9]+")
// Add to Firestore
if (mutableNewDocumentId.value.isNotEmpty() && mutableNewContactNumber.value.isNotEmpty()) {
if (mutableNewContactNumber.value.length == 11 && pattern.matches(mutableNewContactNumber.value)) {
val db = Firebase.firestore
db
.collection("Emergency Contacts")
.document("$finalMunicipalityForm")
.collection("Firefighters")
.document(mutableNewDocumentId.value)
.set(
hashMapOf(
"contacts" to mutableNewContactNumber.value
)
)
.addOnSuccessListener {
Log.d("AddField", "New firefighter added successfully")
Toast.makeText(context, "New firefighter added successfully", Toast.LENGTH_SHORT).show()
mutableNewDocumentId.value = ""
mutableNewContactNumber.value = ""
}
.addOnFailureListener { e ->
Log.e("AddField", "Error adding firefighter", e)
Toast.makeText(context, "Error adding firefighter", Toast.LENGTH_SHORT).show()
}
} else {
Log.d("AddField", "Invalid phone number. Please enter a 11-digit number.")
}
} else {
Log.d("AddField", "Empty fields. Please enter both document ID and contact number.")
}
},
shape = RoundedCornerShape(10.dp),
content = {
Icon(
imageVector = Icons.Default.Check,
contentDescription = null,
tint = Color.White,
modifier = Modifier.size(30.dp)
)
},
modifier = Modifier
.align(Alignment.End) // Align the button to the right
.padding(horizontal = 25.dp) // Add some horizontal padding
)
}
}
}`
I am trying to update my UI whenever there is a new data or updated data or deleted data being process.