Возвращение на аутентификацию при перезагрузке UI после смены темы приложения при первом запуске приложения
При первом запуске приложения моего и перехода в настройки(код фрагмента настроек представлен) при смене темы перезагружается UI и выкидывает на авторизацию Firebase,помогите решить проблему, первое мобильное приложение и много чего еще не понятно.
package com.example.coursework.screens.settings
import android.app.Activity
import android.app.AlertDialog
import android.content.Intent
import android.content.res.Configuration
import android.net.Uri
import android.os.Bundle
import android.provider.Settings
import android.text.TextUtils
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatDelegate
import androidx.core.view.isVisible
import com.example.coursework.MainActivity
import com.example.coursework.databinding.FragmentSettingsBinding
import com.example.coursework.repositories.User.UserInfo
import com.example.coursework.repositories.User.UserRepository
import com.google.android.gms.auth.api.signin.GoogleSignIn
import com.google.android.gms.auth.api.signin.GoogleSignInOptions
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.FirebaseUser
import com.google.firebase.auth.UserProfileChangeRequest
import com.google.firebase.storage.FirebaseStorage
import com.google.firebase.storage.StorageReference
import com.squareup.picasso.Picasso
class Settings : Fragment() {
private lateinit var binding: FragmentSettingsBinding
private val repository = UserRepository()
private lateinit var currentUser: UserInfo
private var currentTheme: Int = 0
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = FragmentSettingsBinding.inflate(layoutInflater, container, false)
val currentTheme = getSelectedTheme()
AppCompatDelegate.setDefaultNightMode(currentTheme)
binding.themePreference.text = "App theme now: ${currentTheme}"
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
FirebaseAuth.getInstance().currentUser?.let {
binding.pageProgress.isVisible = true
repository.getCurrentUserById(it, object : UserRepository.FetchSportsmanListener {
override fun onFetchSportsman(user: UserInfo) {
currentUser = user
showDetails(currentUser, it)
}
})
}
val googleSignInClient =
GoogleSignIn.getClient(requireContext(), GoogleSignInOptions.DEFAULT_SIGN_IN)
//Logout function
binding.logoutButton.setOnClickListener {
AlertDialog.Builder(requireContext())
.setTitle("You have pressed the logout button")
.setMessage("Are you sure you want to logout?")
.setNegativeButton("No, I don't want", null)
.setPositiveButton("Yes, I am really sure") { _, _ ->
FirebaseAuth.getInstance().signOut()
googleSignInClient.signOut()
startActivity(Intent(requireContext(), MainActivity::class.java))
requireActivity().finish()
}
.show()
}
// Theme changing
binding.themePreference.setOnClickListener {
showThemeDialog()
}
// Notifications in settings
binding.notifications.setOnClickListener {
AlertDialog.Builder(requireContext())
.setTitle("Notifications Disabled")
.setMessage("Please enable notifications for this app to receive reminders.")
.setPositiveButton("Enable") { _, _ ->
// app settings notifications enabled
val intent = Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)
intent.putExtra(Settings.EXTRA_APP_PACKAGE, requireActivity().packageName)
startActivity(intent)
}
.setNegativeButton("Cancel", null)
.show()
}
}
private fun showDetails(currentUser: UserInfo, it: FirebaseUser) {
binding.updateUserName.setText(currentUser.displayName)
binding.email.text = it.email
currentUser.photo?.let {
if (it.isNotEmpty()) {
Picasso.get().load(currentUser.photo.toString()).into(binding.userPhoto)
}
}
binding.userPhoto.setOnClickListener {
val intent = Intent()
intent.type = "image/*"
intent.action = Intent.ACTION_GET_CONTENT
profilePhotoChooser.launch(intent)
}
binding.updateUserPhoto.setOnClickListener {
FirebaseAuth.getInstance().currentUser?.uid?.let {
updateProfilePhoto(it)
}
}
binding.name.setEndIconOnClickListener {
updateUserName()
}
binding.pageProgress.isVisible = false
}
private fun updateUserName() {
binding.pageProgress.isVisible = true
if (TextUtils.isEmpty(binding.updateUserName.text)) {
binding.updateUserName.error = "Name is empty!"
return
}
val request = UserProfileChangeRequest.Builder()
.setDisplayName(binding.updateUserName.text.toString())
.build()
FirebaseAuth.getInstance().currentUser?.updateProfile(request)
?.addOnCompleteListener {
if (it.isSuccessful) {
updateDatabaseUser()
binding.pageProgress.isVisible = false
}
}
}
private fun updateProfilePhoto(userId: String) {
binding.pageProgress.isVisible = true
val ref: StorageReference = FirebaseStorage.getInstance().reference
.child("profile_photos/${userId}")
profilePhotoUri?.let {
ref.putFile(it).addOnSuccessListener {
ref.downloadUrl.addOnSuccessListener { uri ->
updateFirebaseUserPhoto(uri)
updateDatabaseUser(uri.toString())
binding.pageProgress.isVisible = false
}
}
}
}
private fun updateDatabaseUser(path: String = currentUser.photo ?: "") {
val user = UserInfo(
displayName = binding.updateUserName.text.toString(),
uid = FirebaseAuth.getInstance().currentUser!!.uid,
photo = path
)
UserRepository().createOrUpdateUser(user)
}
private fun updateFirebaseUserPhoto(uri: Uri) {
val request = UserProfileChangeRequest.Builder()
.setPhotoUri(uri)
.build()
FirebaseAuth.getInstance().currentUser?.updateProfile(request)
}
private var profilePhotoUri: Uri? = null
private var profilePhotoChooser =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK) {
result.data?.let { imageUri ->
binding.userPhoto.setImageURI(imageUri.data)
profilePhotoUri = imageUri.data
}
}
}
private fun showThemeDialog() {
val themes = arrayOf(
"Light",
"Dark",
"System default"
)
val checkedItem = when (binding.themePreference.text.toString()) {
"Light" -> 0
"Dark" -> 1
else -> 2
}
AlertDialog.Builder(requireContext())
.setTitle("Select Application Theme")
.setSingleChoiceItems(themes, checkedItem) { dialog, which ->
val selectedTheme = when (which) {
0 -> AppCompatDelegate.MODE_NIGHT_NO
1 -> AppCompatDelegate.MODE_NIGHT_YES
else -> AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
}
AppCompatDelegate.setDefaultNightMode(selectedTheme)
currentTheme = selectedTheme
dialog.dismiss()
}
.setNegativeButton("Cancel", null)
.show()
}
private fun getSelectedTheme(): Int {
return when (resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) {
Configuration.UI_MODE_NIGHT_NO -> AppCompatDelegate.MODE_NIGHT_NO
Configuration.UI_MODE_NIGHT_YES -> AppCompatDelegate.MODE_NIGHT_YES
else -> AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
}
}
}
а также хмл код фрагмента
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/frameLayout4"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:theme="@style/ElementTheme"
tools:context=".screens.settings.Settings">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/constraintLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
android:background="@drawable/text_border"
android:hint="@string/display_user_email"
android:padding="24dp"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/name" />
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/userPhoto"
android:layout_width="128dp"
android:layout_height="128dp"
android:layout_margin="8dp"
android:scaleType="fitXY"
android:src="@drawable/baseline_verified_user_24"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/updateUserPhoto"
android:layout_width="48dp"
android:layout_height="48dp"
android:src="@drawable/ic_save"
app:layout_constraintBottom_toBottomOf="@+id/userPhoto"
app:layout_constraintEnd_toEndOf="@+id/userPhoto"
app:layout_constraintStart_toEndOf="@+id/userPhoto"
app:layout_constraintTop_toTopOf="@+id/userPhoto"
tools:ignore="ContentDescription" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
android:hint="@string/display_user_name"
app:endIconDrawable="@drawable/ic_save"
app:endIconMode="custom"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/userPhoto">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/updateUserName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="16dp"
tools:ignore="VisualLintTextFieldSize" />
</com.google.android.material.textfield.TextInputLayout>
<Button
android:id="@+id/logout_button"
android:layout_width="129dp"
android:layout_height="52dp"
android:layout_marginTop="32dp"
android:layout_marginEnd="16dp"
android:text="@string/logout_button"
android:textAllCaps="false"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/userPhoto"
app:layout_constraintTop_toBottomOf="@+id/email" />
</androidx.constraintlayout.widget.ConstraintLayout>
<ProgressBar
android:id="@+id/pageProgress"
android:layout_width="64dp"
android:layout_height="64dp"
android:theme="@style/ElementTheme"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/themePreference"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="64dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
android:background="@drawable/text_border"
android:padding="16dp"
android:text=""
android:textSize="16sp"
app:layout_constraintBottom_toTopOf="@+id/notifications"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/constraintLayout" />
<TextView
android:id="@+id/notifications"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="32dp"
android:background="@drawable/text_border"
android:padding="16dp"
android:text="@string/settings_notifications"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/themePreference" />
</androidx.constraintlayout.widget.ConstraintLayout>