Search code examples
androidfirebase-realtime-databasefirebase-authenticationandroid-jetpack-composecompose-recomposition

How to display current username in Text (Jetpack Compose) using Firebase and Kotlin?


So, I have a Firebase Realtime Database with user's name. App should retrieve username of who tries to log in.

Firebase Realtime Database

I need to display current user's "name" in Text() with Jetpack Compose. To the place where &username in the picture below.

Where to put user's name

This is what I have tried:

private val rootRef = FirebaseDatabase.getInstance().reference
private val uid = FirebaseAuth.getInstance().currentUser!!.uid
private val uidRef = rootRef.child("users").child(uid)

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContent {
        MyPassTheme {
            initFirebase()
            WelcomeScreen()

            uidRef.get().addOnCompleteListener { task ->
                if (task.isSuccessful) {
                    val snapshot = task.result
                    val username = snapshot?.child("name")?.getValue(String::class.java)
                    Toast.makeText(baseContext, "$username",
                        Toast.LENGTH_SHORT).show()
                }
            }

But in WelcomeScreen() I cannot update $username from addOnCompleteListener.

@Composable
private fun WelcomeScreen() {
    Box(
        modifier = Modifier
            .fillMaxSize()
            .background(blue69),
    )
    Column(
        modifier = Modifier
            .height(605.dp)
            .fillMaxSize()
            .padding(5.dp),
        verticalArrangement = Arrangement.SpaceEvenly,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Card(
            shape = RoundedCornerShape(20.dp),
            elevation = 10.dp,
            modifier = paddingModifier
                .height(2.dp)
        ) {
            Text(text = widthOnTopBar, modifier = paddingModifier)
        }
    }
    Column(
        modifier = Modifier
            .padding(30.dp)
            .width(1500.dp)
            .height(270.dp)
            .fillMaxWidth()
            .wrapContentSize(Alignment.BottomCenter)
    ) {
        Text(
            modifier = Modifier,
            text = "&username",
            textAlign = TextAlign.Center,
            style = MaterialTheme.typography.h4.copy(
                shadow = Shadow(
                    offset = Offset(2f, 2f),
                    blurRadius = 1f
                ),
                color = Color.White,
                fontSize = 45.sp,
                fontFamily = montserrat_bold
            )
        )
    }

I suppose there is something about data classes and OOP, but i do not know how to do it.


Solution

  • Not sure if this would work, but you can try this.

    We have added a userName state that will be updated from your addOnCompleteListener callback, and when it changes, it will update your WelcomeScreen

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MyPassTheme {
    
                var userName by remember { mutableStateOf("") }
                ...
                WelcomeScreen(userName)
    
                uidRef.get().addOnCompleteListener { task ->
                    if (task.isSuccessful) {
                        val snapshot = task.result
                        userName = snapshot?.child("name")?.getValue(String::class.java)
                        Toast.makeText(
                            baseContext, "$username",
                            Toast.LENGTH_SHORT
                        ).show()
                    }
                }
            }
        }
    }
    

    and your modified WelcomeScreen

    @Composable
    private fun WelcomeScreen(userName: String) {
    
        ...
    
        Column(
             ...
        ) {
            Text(
                ...
                text = userName,
                ...
            )
        }
    }