You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Jetpack Compose中结合Firebase与Kotlin显示当前用户名

解决Jetpack Compose中Firebase实时数据库用户名显示问题

核心问题

你当前的代码无法更新UI是因为Jetpack Compose是声明式UI框架,UI由状态驱动。直接在addOnCompleteListener中获取的username无法触发Compose的重组,需要用Compose的状态变量来管理数据。

修复步骤

1. 用状态变量管理用户名

在setContent内部,通过remember和mutableStateOf创建可观察的状态变量,用来存储用户名和加载状态:

var username by remember { mutableStateOf<String?>(null) }
var isLoading by remember { mutableStateOf(true) }

2. 用LaunchedEffect执行Firebase数据请求

LaunchedEffect是Compose中专门用于执行异步操作的组件,能确保数据请求只在组件初始化时执行一次:

LaunchedEffect(Unit) {
    val task = uidRef.get()
    if (task.isSuccessful) {
        val snapshot = task.result
        username = snapshot?.child("name")?.getValue(String::class.java)
        isLoading = false
    } else {
        Toast.makeText(baseContext, "获取用户名失败", Toast.LENGTH_SHORT).show()
        isLoading = false
    }
}

3. 修改WelcomeScreen接收状态参数

让WelcomeScreen接收username和isLoading参数,根据状态显示对应内容:

@Composable
private fun WelcomeScreen(username: String?, isLoading: Boolean) {
    Box(
        modifier = Modifier
            .fillMaxSize()
            .background(blue69),
    )
    // 原有顶部Card布局部分...
    Column(
        modifier = Modifier
            .padding(30.dp)
            .width(1500.dp)
            .height(270.dp)
            .fillMaxWidth()
            .wrapContentSize(Alignment.BottomCenter)
    ) {
        if (isLoading) {
            // 加载中显示进度条
            CircularProgressIndicator(color = Color.White)
        } else {
            Text(
                modifier = Modifier,
                text = username ?: "Guest", // 空值时显示默认文本
                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
                )
            )
        }
    }
}

4. 在setContent中传递状态参数

更新setContent里的调用,把状态变量传给WelcomeScreen:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    // 先判断用户是否登录,避免空指针
    val currentUser = FirebaseAuth.getInstance().currentUser
    if (currentUser == null) {
        // 未登录则跳转到登录页
        startActivity(Intent(this, LoginActivity::class.java))
        finish()
        return
    }
    val uid = currentUser.uid
    val rootRef = FirebaseDatabase.getInstance().reference
    val uidRef = rootRef.child("users").child(uid)

    setContent {
        MyPassTheme {
            initFirebase()
            var username by remember { mutableStateOf<String?>(null) }
            var isLoading by remember { mutableStateOf(true) }

            LaunchedEffect(Unit) {
                val task = uidRef.get()
                if (task.isSuccessful) {
                    val snapshot = task.result
                    username = snapshot?.child("name")?.getValue(String::class.java)
                    isLoading = false
                } else {
                    Toast.makeText(baseContext, "获取用户名失败", Toast.LENGTH_SHORT).show()
                    isLoading = false
                }
            }

            WelcomeScreen(username = username, isLoading = isLoading)
        }
    }
}

额外优化

如果需要实时监听用户名的变化(比如数据库中用户名更新时UI自动刷新),可以用addValueEventListener替代get():

LaunchedEffect(Unit) {
    val listener = object : ValueEventListener {
        override fun onDataChange(snapshot: DataSnapshot) {
            username = snapshot.child("name").getValue(String::class.java)
            isLoading = false
        }

        override fun onCancelled(error: DatabaseError) {
            Toast.makeText(baseContext, "监听失败: ${error.message}", Toast.LENGTH_SHORT).show()
            isLoading = false
        }
    }
    uidRef.addValueEventListener(listener)
    // 组件销毁时移除监听,避免内存泄漏
    DisposableEffect(Unit) {
        onDispose {
            uidRef.removeEventListener(listener)
        }
    }
}

内容的提问来源于stack exchange,提问作者Artorius

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 17:35:26