我的代码未显示我的个人资料屏幕内容以查看我的个人资料屏幕

问题描述 投票:0回答:1

这是我的视图模型



@HiltViewModel
class galBaatviewModel @Inject constructor(
    val auth: FirebaseAuth,
    var db : FirebaseFirestore,
    val storage : FirebaseStorage

) : ViewModel() {


    var inProcess = mutableStateOf(false)
    val eventMutableState = mutableStateOf<Event<String>?>(null)
    var signIn = mutableStateOf(false)
    val userData = mutableStateOf<UserData?>(null)
    init {

        val currentUser = auth.currentUser
        signIn.value = currentUser!= null
        currentUser?.uid?.let {
            getUserData(it)
        }

    }


    fun signUp(name: String, number: String, email: String, Password: String) {
        inProcess.value = true
        if(name.isEmpty() or number.isEmpty() or email.isEmpty() or Password.isEmpty()){
            HandleException(customMessage = "Please fill all fields")
            return
        }
        inProcess.value = true
        db.collection(USER_NODE).whereEqualTo("number",number).get().addOnSuccessListener {
            if(it.isEmpty){
                auth.createUserWithEmailAndPassword(email, Password).addOnCompleteListener {

                    if (it.isSuccessful) {
                        signIn.value = true
                        createOrUpdateProfile(name,number)
                    } else {
                        HandleException(it.exception, customMessage = "Sign Up failed")
                    }
                }
            }
            else{
                HandleException(customMessage = "number already exist")
                inProcess.value = false
            }
        }

    }

    fun LogIn(email: String,Password: String){
        if(email.isEmpty() or Password.isEmpty()){
            HandleException(customMessage = "Please fill all the fields")
        }
        else{
            inProcess.value = true
            auth.signInWithEmailAndPassword(email,Password).addOnCompleteListener {
                if(it.isSuccessful){
                    signIn.value = true
                    inProcess.value = false
                    auth.currentUser?.uid?.let {
                        getUserData(it)
                    }
                }else{
                    HandleException(exception = it.exception, customMessage = "Login failed")
                }
            }
        }
    }

    fun uploadProfileImage(uri : Uri){
            uploadImage(uri){
                createOrUpdateProfile(imageUrl = it.toString())
            }
    }

    fun uploadImage(uri: Uri,onSuccess: (Uri)->Unit){
        inProcess.value = true
        val storageRef = storage.reference
        val uuid = UUID.randomUUID()
        val imageRef = storageRef.child("images/$uuid")
        val uploadTask = imageRef.putFile(uri)
        uploadTask.addOnSuccessListener {
            val result = it.metadata?.reference?.downloadUrl
            result?.addOnSuccessListener(onSuccess)
                inProcess.value = false


        }
            .addOnFailureListener{
                HandleException(it)
            }
    }

    fun createOrUpdateProfile(name: String?=null,number: String?=null,imageUrl:String?=null){

        var uid=auth.currentUser?.uid
        val userData =UserData(
            userId = uid,
            name = name?:userData.value?.name,
            number = number?: userData.value?.number,
            imageUrl = imageUrl?: userData.value?.imageUrl
        )
        uid?.let{
            inProcess.value = true
            db.collection(USER_NODE).document(uid).get().addOnSuccessListener {
                if(it.exists()){
                    //update user data
                }
                else{
                    db.collection(USER_NODE).document(uid).set(userData)
                    inProcess.value = false
                    getUserData(uid )
                }
            }
                .addOnFailureListener{
                    HandleException(it, "cannot retrieve user")
                }

        }
    }

    private fun getUserData(uid: String) {
        inProcess.value = true
        db.collection(USER_NODE).document(uid).addSnapshotListener{
            value, error->
            if(error!= null){
                HandleException(error,"can not retrieve user")
            }
            if(value != null){
                var user = value.toObject<UserData>()
                userData.value = user
                inProcess.value = false
            }
        }
    }

    fun HandleException(exception: Exception? = null, customMessage: String = "") {
        Log.e("GalBaat", "GalBaat exception: ", exception)
        exception?.printStackTrace()
        val errorMsg = exception?.localizedMessage ?: ""
        val message = if (customMessage.isNullOrEmpty()) errorMsg else customMessage

        eventMutableState.value = Event(message)
        inProcess.value = false
    }
}


这是我的个人资料屏幕代码

package com.example.galbaat.screen



@Composable
fun ProfileScreen(navController: NavController,vm : galBaatviewModel) {
    val inProgress = vm.inProcess.value
    if(inProgress){
        CommonProgressBar()
    }else{
        Column {
            ProfileContent(
                modifier = Modifier
                    .weight(1f)
                    .verticalScroll(rememberScrollState())
                    .padding(8.dp),
                vm =vm,
                name = "",
                number = "",
                onNameChange = {""},
                onNumberChange = {""},
                onSave = {},
                onBack = {},
                onLogOut ={}
            )
            BottomNavigationMenu(selectedItem = BottomNavigationItem.PROFILE, navController = navController)
        }

    }



}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ProfileContent(

    vm: galBaatviewModel,
    name: String,
    number:String,
    onNameChange:(String)->Unit,
    onNumberChange:(String)->Unit,
    onBack : ()->Unit,
    onSave: ()-> Unit,
    onLogOut: () -> Unit,
    modifier: Modifier,) {
    val imageUrl = vm.userData.value?.imageUrl
    Column {
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .padding(8.dp),
            horizontalArrangement = Arrangement.SpaceBetween,
        ) {
            Text(text = "BACK", Modifier.clickable {
                onBack.invoke()
            })
            Text(text = "SAVE", Modifier.clickable {
                onSave.invoke()
            })
            CommonDivider()
            ProfileImage(imageUrl = imageUrl, vm = vm)

            CommonDivider()
            Row(
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(4.dp),
                verticalAlignment = Alignment.CenterVertically
            )
            {
                Text(text = "Name", modifier = Modifier.width(100.dp))
                TextField(
                    value = name, onValueChange = onNameChange,
                    colors = TextFieldDefaults.textFieldColors(
                        focusedTextColor = Color.Black,
                        containerColor = Color.Transparent

                    )
                )
            }
            Row(
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(4.dp), verticalAlignment = Alignment.CenterVertically
            )
            {
                Text(text = "Number", modifier = Modifier.width(100.dp))
                TextField(
                    value = number, onValueChange = onNumberChange,
                    colors = TextFieldDefaults.textFieldColors(
                        focusedTextColor = Color.Black,
                        containerColor = Color.Transparent
                    )
                )
            }
            CommonDivider()
            Row(
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(16.dp),
                horizontalArrangement = Arrangement.Center
            ) {
                Text(text = "Logout", modifier = Modifier.clickable {
                    onLogOut.invoke()
                })
            }
        }
    }

}

@Composable
fun ProfileImage(imageUrl:String?,vm: galBaatviewModel){
    val launcher = rememberLauncherForActivityResult(contract = ActivityResultContracts.GetContent()
    ) {
            uri ->
        uri?.let {
            vm.uploadProfileImage(uri)
        }

    }
    Box(modifier = Modifier.height(intrinsicSize = IntrinsicSize.Min)){
        Column(modifier = Modifier
            .padding(8.dp)
            .fillMaxWidth()
            .clickable {
                launcher.launch("image/*")
            },
            horizontalAlignment = Alignment.CenterHorizontally) {
            Card(shape = CircleShape,
                modifier = Modifier
                    .padding(8.dp)
                    .size(100.dp)) {
                CommonImage(data = imageUrl)
            }
            Text(text = "Change Profile Picture")
        }
        if(vm.inProcess.value)
            CommonProgressBar()

    }
}

这是我的主要活动

package com.example.galbaat




sealed class DestinationScreens(var route: String){
object SignUp : DestinationScreens("signup")
object Login : DestinationScreens("login")
object profile : DestinationScreens("ProfileScreen")
object ChatList : DestinationScreens("chatList")
object SingleChat : DestinationScreens("singleChat/{chatId}"){
    fun createRoute(id: String) = "SingleChat/$id"
}
    object StatusList : DestinationScreens("statusList")
object SingleStatus : DestinationScreens("singleStatus/{UserId}"){
    fun createRoute(Userid: String) = "SingleChat/$Userid"
}
}
@AndroidEntryPoint

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            GALBAATTheme {
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    chatAppNavigation()
                }
            }
        }
    }
    @Composable
    fun chatAppNavigation(){
        val navController = rememberNavController()
        var vm = hiltViewModel<galBaatviewModel>()
        NavHost(navController = navController, startDestination = DestinationScreens.SignUp.route){
            composable(DestinationScreens.SignUp.route){
                SignUp(navController,vm)
            }
            composable(DestinationScreens.Login.route){
                loginScreen(navController=navController,vm = vm)
            }
            composable(DestinationScreens.ChatList.route){
                chatScreen(navController = navController , vm = vm)
            }
            composable(DestinationScreens.StatusList.route){
                StatusScreen(navController = navController , vm = vm)
            }
            composable(DestinationScreens.profile.route){
                ProfileScreen(navController = navController , vm = vm)
            }

        }

    }
}

我尝试正确路由它,但在我的 prfile 上它没有显示任何内容,我已附加我的个人资料屏幕代码以及我的视图模型代码和主要活动代码,这似乎更多是我无法解决的函数调用问题

android firebase kotlin android-jetpack-compose dagger-hilt
1个回答
0
投票

在您的撰写函数中,不要调用

.value
,而是使用
collectAsState
, 当您调用
.value
时,它不会对更改做出反应,但是使用
collectAsState
时,它将用新数据重新组合可组合项,请全部替换...

例如这个:

vm.userData.value?.imageUrl
将更改为: vm.userData.collectAsState()?.imageUrl`

希望对你有帮助

© www.soinside.com 2019 - 2024. All rights reserved.