Issue
I am trying to defer updates to Firebase Database only after user press the ImeAction.Done in a TextField. (Such that the user can update the TextField, but we will update the database only when user press the Done button. )
This however results in 2 sources of truth (one from the temporary user update, and the other from the firebase database).
If I remember the temporary field, user updates are reflected, but it will not update when firebase does the first read/ or when the user selects another path.
//PROBLEM: tempDisplayName is only updated once and it will not register changes from firebase.
var tempDisplayName by remember {mutableStateOf(firebaseDataClass?.displayName?:"")}
HoistDisplayName(tempDisplayName, { tempDisplayName = it},
{
firebaseDataClass?.displayname = tempDisplayName
updateDatabase(firebaseDataClass)})
if I use the firebase field, then when user selects another path the Db changes are reflected, but user updates to TextField no longer works.
//Now the field is updated when user selects another branch on firebase
//(firebaseDataClass updated).
//PROBLEM: user updates to the TextField is no longer reflected.
val tempDisplayName = firebaseDataClass?.displayName?:""
HoistDisplayName(tempDisplayName, { tempDisplayName = it},
{
firebaseDataClass?.displayname = tempDisplayName
updateDatabase(firebaseDataClass)})
The following is the Hoisted composable.
@Composable
private fun HoistDisplayName(
display: String,
onUpdate: (String) -> Unit,
onDone: () -> Unit
) {
val localFocusManager = LocalFocusManager.current
OutlinedTextField(value = display,
label = { Text(text = "Your name") },
onValueChange = { onUpdate.invoke(it) },
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions {
localFocusManager.clearFocus()
onDone.invoke()
})
}
So how do I fix the code such that
- updates from firebase DB will be reflected on the TextField (replaces all temporary changes)
- temporary changes are also displayed on the TextField
Solution
You need remember + mutableStateOf in order to text field to work.
And you need to update it value when your firebaseDataClass?.displayName changes. To do so you need to pass this value as a remember key: when realDisplayName is different from last render time, tempDisplayName will be updated with new value.
val realDisplayName = firebaseDataClass?.displayName?:""
var tempDisplayName by remember(realDisplayName) { mutableStateOf(realDisplayName) }
Answered By - Philip Dukhov
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.