Как я могу загрузить изображение из приложения Android с помощью облачного хранилища Firestore и увидеть его на веб-страAndroid

Форум для тех, кто программирует под Android
Ответить Пред. темаСлед. тема
Anonymous
 Как я могу загрузить изображение из приложения Android с помощью облачного хранилища Firestore и увидеть его на веб-стра

Сообщение Anonymous »


Я пытался создать приложение для Android, используя Kotlin и Jetpack Compose.
У меня возникла проблема с загрузкой изображений при регистрации.
Я создал функцию и обработал ее с помощью Compose, и она работает отлично, но продолжает загружать изображения в виде массива в мой облачный Firestore, а не в виде реального изображения, оно не показывает никакого изображения.
Я хочу понять, в чем моя проблема.

Вот мой код пользовательского интерфейса
пакет com.example.masaleh.ui импортировать android.content.Context импортировать android.net.Uri импортировать androidx.activity.compose.rememberLauncherForActivityResult импортировать androidx.activity.result.contract.ActivityResultContracts импортировать androidx.compose.foundation.Image импортировать androidx.compose.foundation.layout.Arrangement импортировать androidx.compose.foundation.layout.Column импортировать androidx.compose.foundation.layout.Row импортировать androidx.compose.foundation.layout.Spacer импортировать androidx.compose.foundation.layout.fillMaxSize импортировать androidx.compose.foundation.layout.fillMaxWidth импортировать androidx.compose.foundation.layout.height импортировать androidx.compose.foundation.layout.padding импортировать androidx.compose.foundation.layout.size импортировать androidx.compose.foundation.layout.width импортировать androidx.compose.foundation.text.KeyboardOptions импортировать androidx.compose.material.icons.Icons импортировать androidx.compose.material.icons.filled.AccountBox импортировать androidx.compose.material3.Button импортировать androidx.compose.material3.ButtonDefaults импортировать androidx.compose.material3.ExperimentalMaterial3Api импортировать androidx.compose.material3.Icon импортировать androidx.compose.material3.IconButton импортировать androidx.compose.material3.MaterialTheme импортировать androidx.compose.material3.Text импортировать androidx.compose.material3.TextField импортировать androidx.compose.runtime.Composable импортировать androidx.compose.runtime.mutableStateListOf импортировать androidx.compose.runtime.remember импортировать androidx.compose.ui.Alignment импортировать androidx.compose.ui.Modifier импортировать androidx.compose.ui.res.stringResource импортировать androidx.compose.ui.text.input.KeyboardType импортировать androidx.compose.ui.unit.dp импортировать androidx.lifecycle.viewmodel.compose.viewModel импортировать androidx.navigation.NavController импортировать coin.compose.rememberAsyncImagePainter импортировать com.example.masaleh.R импортировать com.example.masaleh.model.SignUpWorkerViewModel импортировать com.example.masaleh.ui.theme.mediumShape @OptIn(ExperimentalMaterial3Api::class) @Композитный весело SignUpScreenWorker( SignUpWorkerViewModel: SignUpWorkerViewModel = viewModel(), навконтроллер: Навконтроллер, контекст: Контекст ) { val buttonShape = mediumShape val imageUri = помните {mutableStateListOf() } val launcher = RememberLauncherForActivityResult(ActivityResultContracts.GetMultipleContents()) { uris: Список? -> урис?.let { изображениеUri.clear() imageUri.addAll(оно) } } Столбец( модификатор = Модификатор .padding(8.dp) .fillMaxSize(), HorizontalAlignment = Alignment.CenterHorizontally ) { Ряд( модификатор = Модификатор .fillMaxWidth() .padding(8.dp), вертикальноеВыравнивание = Выравнивание.ЦентрВертикально ) { // Кнопка загрузки изображения ЗначокКнопка( onClick = { launcher.launch("изображение/*") // Запускаем средство выбора файлов }, модификатор = Modifier.padding(end = 8.dp) ) { Икона( imageVector = Icons.Default.AccountBox, ContentDescription = ноль, оттенок = MaterialTheme.colorScheme.onBackground ) } // Загруженные изображения imageUri.forEach { uri -> val Painter = RememberAsyncImagePainter (uri) Изображение( художник = художник, contentDescription = stringResource(R.string.img_uri), модификатор = Модификатор .size(80.dp) .padding(вертикаль = 8.dp) ) } } Столбец( модификатор = Modifier.fillMaxWidth(), HorizontalAlignment = Alignment.CenterHorizontally ) { Т Это Икс т ( т Это Икс т = с т р я н г р Это с О в р с Это ( р . с т р я н г . с я г н в п _ н Это В _ а с с О в н т ) , с О л О р = М а т Это р я а л Т час Это м Это . с О л О р С с час Это м Это . п р я м а р и , с т и л Это = М а т Это р я а л Т час Это м Это . т и п О г р а п час и . д я с п л а и л а р г Это , м О д я ж я Это р = М О д я ж я Это р . п а д д я н г ( 8 . д п ) ) Т Это Икс т Ф я Это л д ( м О д я ж я Это р = М О д я ж я Это р . ж я л л М а Икс В я д т час ( ) , в а л в Это = с я г н В п В О р к Это р В я Это В М О д Это л . н а м Это , л а б Это л = { Т Это Икс т ( т Это Икс т = с т р я н г р Это с О в р с Это ( р . с т р я н г . н а м Это _ ж О р _ с я г н в п ) , с О л О р = М а т Это р я а л Т час Это м Это . с О л О р С с час Это м Это . п р я м а р и , с т и л Это = М а т Это р я а л Т час Это м Это . т и п О г р а п час и . д я с п л а и М Это д я в м ) } , п л а с Это час О л д Это р = { Т Это Икс т ( т Это Икс т = с т р я н г р Это с О в р с Это ( р . с т р я н г . п в т _ и О в р _ н а м Это ) , с О л О р = М а т Это р я а л Т час Это м Это . с О л О р С с час Это м Это . п р я м а р и , с т и л Это = М а т Это р я а л Т час Это м Это . т и п О г р а п час и . д я с п л а и М Это д я в м ) } , к Это и б О а р д О п т я О н с = К Это и б О а р д О п т я О н с ( к Это и б О а р д Т и п Это = К Это и б О а р д Т и п Это . Т Это Икс т ) , О н В а л в Это С час а н г Это = { я т - & г т ; с я г н В п В О р к Это р В я Это В М О д Это л . н а м Это = я т } ) С п а с Это р ( м О д я ж я Это р = М О д я ж я Это р . час Это я г час т ( 8 . д п ) ) Т Это Икс т Ф я Это л д ( м О д я ж я Это р = М О д я ж я Это р . ж я л л М а Икс В я д т час ( ) , в а л в Это = с я г н В п В О р к Это р В я Это В М О д Это л . дж О б Т и п Это , л а б Это л = { Т Это Икс т ( т Это Икс т = с т р я н г р Это с О в р с Это ( р . с т р я н г . с Это р в я с Это с _ и О в _ л О к я н г _ ж О р _ я т ) , с О л О р = М а т Это р я а л Т час Это м Это . с О л О р С с час Это м Это . п р я м а р и , с т и л Это = М а т Это р я а л Т час Это м Это . т и п О г р а п час и . д я с п л а и М Это д я в м ) } , п л а с Это час О л д Это р = { Т Это Икс т ( т Это Икс т = с т р я н г р Это с О в р с Это ( р . с т р я н г . дж О б _ т и п Это _ д Это с с р я п т я О н ) , с О л О р = М а т Это р я а л Т час Это м Это . с О л О р С с час Это м Это . п р я м а р и , с т и л Это = М а т Это р я а л Т час Это м Это . т и п О г р а п час и . д я с п л а и М Это д я в м ) } , к Это и б О а р д О п т я О н с = К Это и б О а р д О п т я О н с ( к Это и б О а р д Т и п Это = К Это и б О а р д Т и п Это . Т Это Икс т ) , О н В а л в Это С час а н г Это = { я т - & г т ; с я г н В п В О р к Это р В я Это В М О д Это л . дж О б Т и п Это = я т } ) С п а с Это р ( м О д я ж я Это р = М О д я ж я Это р . час Это я г час т ( 8 . д п ) ) Т Это Икс т Ф я Это л д ( м О д я ж я Это р = М О д я ж я Это р . ж я л л М а Икс В я д т час ( ) , в а л в Это = с я г н В п В О р к Это р В я Это В М О д Это л . дж О б п р О ж я с я Это н с и л Это в Это л , л а б Это л = { Т Это Икс т ( т Это Икс т = с т р я н г р Это с О в р с Это ( р . с т р я н г . Дж О б _уровень_профессионализма), цвет = MaterialTheme.colorScheme.primary, стиль = MaterialTheme.typography.displayMedium ) }, заполнитель = { Текст( текст = stringResource(R.string.Job_proficiency_level_description), цвет = MaterialTheme.colorScheme.primary, стиль = MaterialTheme.typography.displayMedium ) }, KeyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text), onValueChange = { это -> SignUpWorkerViewModel.jobProficiencyLevel = это } ) Spacer(модификатор = Modifier.height(8.dp)) Текстовое поле( модификатор = Modifier.fillMaxWidth(), значение = SignUpWorkerViewModel.адрес, метка = { Текст( текст = stringResource(R.string.address), цвет = MaterialTheme.colorScheme.primary, стиль = MaterialTheme.typography.displayMedium ) }, заполнитель = { Текст( текст = stringResource(R.string.your_address_here), цвет = MaterialTheme.colorScheme.primary, стиль = MaterialTheme.typography.displayMedium ) }, KeyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text), onValueChange = { это -> SignUpWorkerViewModel.address = это } ) Spacer(модификатор = Modifier.height(8.dp)) Текстовое поле( модификатор = Modifier.fillMaxWidth(), значение = SignUpWorkerViewModel.email, метка = { Текст( текст = stringResource(R.string.email), цвет = MaterialTheme.colorScheme.primary, стиль = MaterialTheme.typography.displayMedium ) }, заполнитель = { Текст( текст = stringResource(R.string.put_your_mail_here), цвет = MaterialTheme.colorScheme.primary, стиль = MaterialTheme.typography.displayMedium ) }, KeyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Email), onValueChange = { это -> SignUpWorkerViewModel.email = это } ) Spacer(модификатор = Modifier.height(8.dp)) Текстовое поле( модификатор = Modifier.fillMaxWidth(), значение = SignUpWorkerViewModel.number, метка = { Текст( текст = stringResource(R.string.number), цвет = MaterialTheme.colorScheme.primary, стиль = MaterialTheme.typography.displayMedium ) }, заполнитель = { Текст( текст = stringResource(R.string.put_your_phone_number), цвет = MaterialTheme.colorScheme.primary, стиль = MaterialTheme.typography.displayMedium ) }, KeyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Phone), onValueChange = { это -> SignUpWorkerViewModel.number = это } ) Spacer(модификатор = Modifier.height(8.dp)) Текстовое поле( модификатор = Modifier.fillMaxWidth(), значение = SignUpWorkerViewModel.пароль, метка = { Текст( текст = stringResource(R.string.password), цвет = MaterialTheme.colorScheme.primary, стиль = MaterialTheme.typography.displayMedium ) }, заполнитель = { Текст( текст = stringResource(R.string.put_your_password), цвет = MaterialTheme.colorScheme.primary, стиль = MaterialTheme.typography.displayMedium ) }, KeyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password), onValueChange = { это -> SignUpWorkerViewModel.password = это } ) } Ряд( модификатор = Модификатор .fillMaxWidth(), ГоризонтальноеРасположение = Расположение.Центр, вертикальноеВыравнивание = Выравнивание.Низ ) { Кнопка( onClick = {signUpWorkerViewModel.onLoginButtonClicked(navController = navController)}, modifier = Modifier.weight(1f), // заполняем максимальный размер форма = кнопкаФорма, цвета = ButtonDefaults.buttonColors(MaterialTheme.colorScheme.primary) ) { Текст( текст = stringResource(id = R.string.login_text), цвет = MaterialTheme.colorScheme.onBackground, стиль = MaterialTheme.typography.displayMedium ) } Spacer(модификатор = Modifier.width(8.dp)) Кнопка( onClick = { SignUpWorkerViewModel.onSignUpButtonClicked( navController = navController, контекст = контекст ) }, модификатор = Modifier.weight(1f), форма = кнопкаФорма, цвета = ButtonDefaults.buttonColors(MaterialTheme.colorScheme.primaryContainer) ) { Текст( текст = stringResource(id = R.string.signup_text), цвет = MaterialTheme.colorScheme.onBackground, стиль = MaterialTheme.typography.displayMedium ) } } } }
модель представления
пакет com.example.masaleh.model импортировать android.content.Context импортировать android.net.Uri импортировать android.widget.Toast импортировать androidx.compose.runtime.getValue импортировать androidx.compose.runtime.mutableStateOf импортировать androidx.compose.runtime.setValue импортировать androidx.lifecycle.ViewModel импортировать androidx.lifecycle.viewModelScope импортировать androidx.navigation.NavController импортировать com.example.masaleh.DestinationScreen импортировать com.google.firebase.auth.FirebaseAuth импортировать com.google.firebase.firestore.FirebaseFirestore импортировать com.google.firebase.storage.FirebaseStorage импортировать kotlinx.coroutines.launch импортировать kotlinx.coroutines.tasks.await класс SignUpWorkerViewModel : ViewModel() { частный вал firebaseAuth = FirebaseAuth.getInstance() частный вал firestore = FirebaseFirestore.getInstance() частное хранилище val = FirebaseStorage.getInstance() вар imgs: List по mutableStateOf(emptyList()) имя переменной: строка от mutableStateOf("") var jobType: строка от mutableStateOf("") var jobProficiencyLevel: строка от mutableStateOf("") адрес var: строка от mutableStateOf("") var электронная почта: строка от mutableStateOf("") номер переменной: строка от mutableStateOf("") пароль var: строка от mutableStateOf("") весело onLoginButtonClicked (navController: NavController) { viewModelScope.launch { } navController.navigate(DestinationScreen.Login.name) } fun onSignUpButtonClicked (navController: NavController, context: Context) { val imageUris = imgs.toList() // Создаем копию URI выбранного изображения val введенное имя = имя val введенныйТипЗадания = ТипЗадания val введенныйJobProficiencyLevel = jobProficiencyLevel val введенный адрес = адрес val введенEmail = адрес электронной почты val введенный номер = число val enterPassword = пароль viewModelScope.launch { пытаться { // Загружаем каждое выбранное изображение val uploadedImageUrls = imageUris.map { uploadImage(it) } если (введенноеИмя.isEmpty() || введенныйJobType.isEmpty() || введенныйJobProficiencyLevel.isEmpty() || введенныйАдрес.isEmpty() || введенныйEmail.isEmpty() || введенныйНомер.isEmpty() || введенныйПароль.isEmpty() ) { // Отображение сообщения об ошибке работникам, сообщающего им, что все поля являются обязательными. Toast.makeText(context, «Все поля обязательны», Toast.LENGTH_SHORT).show() возврат@запуск } // Проверяем, действителен ли адрес электронной почты пользователя. если (!isValidEmailAddress(enteredEmail)) { // Отобразить сообщение об ошибке и сообщить пользователю, что ему необходимо ввести действительный адрес электронной почты. Toast.makeText(context, «Неверный адрес электронной почты», Toast.LENGTH_SHORT).show() возврат@запуск } // Проверяем, используется ли адрес электронной почты пользователя. если (!checkEmailAvailability(enteredEmail)) { // Отобразить сообщение об ошибке и сообщить пользователю, что ему нужно выбрать другой адрес электронной почты. Toast.makeText(context, «Адрес электронной почты уже используется», Toast.LENGTH_SHORT).show() возврат@запуск } // Проверяем, достаточно ли надежен пароль пользователя. if (!isPasswordStrongEnough(enteredPassword)) { // Отобразить сообщение об ошибке и сообщить пользователю, что ему необходимо выбрать более надежный пароль. Toast.makeText(context, «Пароль слишком слабый», Toast.LENGTH_SHORT).show() возврат@запуск } firebaseAuth.createUserWithEmailAndPassword(введенный адрес электронной почты, введенный пароль) .addOnSuccessListener { val workerDocument = Firestore .collection("рабочие") .document(firebaseAuth.currentUser?.email ?: "") рабочийДокумент .набор( хэшMapOf( «Изображение» для загруженныхImageUrls, «имя» для введенного имени, «Тип задания» для введенного типа задания, «Уровень квалификации по специальности» на «EnterJobProficiencyLevel», «Адрес» для введенного адреса, "Число" на введенный номер ) ) navController.navigate(DestinationScreen.Terms.name) } .addOnFailureListener { // Проверка ошибок сервера. val errorCode = getErrorCode(it) если (код ошибки!= ноль) { // Отображение сообщения об ошибке и сообщение пользователю о проблеме с сервером. Toast.makeText(контекст, «Ошибка сервера», Toast.LENGTH_SHORT).show() } } } catch (исключение: Исключение) { // Обработка ошибки регистрации. Toast.makeText(контекст, «Неизвестная ошибка», Toast.LENGTH_SHORT).show() } } } личное развлечение isValidEmailAddress(email: String): Boolean { val emailRegex = Regex("""\w+@[a-zA-Z]+(\.[a-zA-Z]+)+""") вернуть emailRegex.matches(электронная почта) } частная приостановка развлечения checkEmailAvailability(email: String): Boolean { val querySnapshot = firestore.collection("пользователи") .whereEqualTo("электронная почта", электронная почта) .получать() .Ждите() вернуть запросSnapshot.isEmpty } // Функция для загрузки изображения в Cloud Storage и получения URL-адреса загрузки приостановить развлечение uploadImage(imageUri: Uri): List { val StorageRef = хранилище.ссылка val imageRef = StorageRef.child("images/${FirebaseAuth.getInstance().currentUser?.uid}/${imageUri.lastPathSegment}") val uploadTask = imageRef.putFile(imageUri) val TaskSnapshot = uploadTask.await() val downloadUrls = mutableListOf() downloadUrls.add(taskSnapshot.storage.downloadUrl.await()) вернуть URL-адреса загрузки } личное развлечение isPasswordStrongEnough(пароль: String): Boolean { вернуть пароль.длина >= 8 } частное развлечение getErrorCode (e: Exception): String? { // TODO: реализуйте эту функцию, чтобы получить код ошибки из исключения. вернуть ноль } }
Я думаю, проблема с функцией, которая загружает изображение, как оно его загружает и какого типа, но я не вижу проблемы
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Android»