Я пытаюсь загрузить изображения с моего устройства Galery в мое приложение React Native Expo с помощью Firebase, но я получаю ошибку OnSubmitCreatEService [Ошибка: создание каплей из «ArrayBuffer» и «ArrayBufferview» не поддерживается]. Может ли кто -нибудь помочь мне решить это, пожалуйста? Как только я загружаю изображение и проверяю форму < /p>
import React, { useEffect, useState } from 'react';
import {
View,
Text,
TextInput,
StyleSheet,
TouchableOpacity,
ActivityIndicator,
Alert,
ScrollView,
Pressable,
Image,
} from 'react-native';
import { Ionicons } from '@expo/vector-icons';
import * as ImagePicker from 'expo-image-picker';
import * as ImageManipulator from 'expo-image-manipulator';
import * as FileSystem from 'expo-file-system';
import { auth as firebaseAuth, db as firestoreDatabase, storage as firebaseStorage } from '../FirebaseConfig';
import {
addDoc,
collection,
doc,
onSnapshot,
orderBy,
query,
serverTimestamp,
} from 'firebase/firestore';
import { onAuthStateChanged } from 'firebase/auth';
import { ref as createStorageRef, uploadString, getDownloadURL } from 'firebase/storage';
const PRIMARY_COLOR = '#2B1E12';
const MUTED_TEXT_COLOR = '#6b6b6b';
export default function AddNewService({ navigation }) {
const [userIdentifier, setUserIdentifier] = useState(null);
const [isAuthReady, setIsAuthReady] = useState(false);
useEffect(() => {
return onAuthStateChanged(firebaseAuth, (user) => {
setUserIdentifier(user?.uid ?? null);
setIsAuthReady(true);
});
}, []);
// Formulaire
const [serviceName, setServiceName] = useState('');
const [servicePrice, setServicePrice] = useState('');
const [serviceHours, setServiceHours] = useState('0');
const [serviceMinutes, setServiceMinutes] = useState('30');
// Catégories
const [categoriesList, setCategoriesList] = useState([]);
const [isCategoryDropdownOpen, setIsCategoryDropdownOpen] = useState(false);
const [selectedCategory, setSelectedCategory] = useState(null); // { id, name }
// Image locale + téléversement
const [localImageUri, setLocalImageUri] = useState(null);
const [isUploadingImage, setIsUploadingImage] = useState(false);
const [isSavingService, setIsSavingService] = useState(false);
const isFormValid =
serviceName.trim() &&
selectedCategory &&
servicePrice !== '' &&
serviceHours !== '' &&
serviceMinutes !== '';
// Charger la liste des catégories
useEffect(() => {
const categoriesQuery = query(collection(firestoreDatabase, 'categories'), orderBy('name', 'asc'));
const unsubscribe = onSnapshot(categoriesQuery, (snapshot) => {
setCategoriesList(snapshot.docs.map((d) => ({ id: d.id, ...d.data() })));
});
return unsubscribe;
}, []);
async function requestMediaLibraryPermission() {
const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
if (status !== 'granted') throw new Error('Permission refusée');
}
async function pickImageFromLibrary() {
try {
await requestMediaLibraryPermission();
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images,
allowsEditing: true,
quality: 0.9,
});
if (result.canceled) return;
const pickedAsset = result.assets[0];
// Redimensionner / compresser et forcer JPEG
const manipulatedImage = await ImageManipulator.manipulateAsync(
pickedAsset.uri,
[{ resize: { width: 1200 } }],
{ compress: 0.8, format: ImageManipulator.SaveFormat.JPEG }
);
// S’assurer d’un schéma file://
let fileUri = manipulatedImage.uri;
if (!fileUri.startsWith('file://')) {
const target = FileSystem.cacheDirectory + `service-${Date.now()}.jpg`;
await FileSystem.copyAsync({ from: fileUri, to: target });
fileUri = target;
}
setLocalImageUri(fileUri);
} catch (error) {
console.log('pickImageFromLibrary error', error);
Alert.alert('Image', 'Impossible d’ouvrir la galerie.');
}
}
function removeSelectedImage() {
setLocalImageUri(null);
}
async function uploadImageAndGetUrl(fileUri, workerId) {
setIsUploadingImage(true);
try {
const path = `services/${workerId}/${Date.now()}-${Math.random().toString(36).slice(2, 7)}.jpg`;
const base64 = await FileSystem.readAsStringAsync(fileUri, { encoding: FileSystem.EncodingType.Base64 });
const ref = createStorageRef(firebaseStorage, path);
const dataUrl = `data:image/jpeg;base64,${base64}`;
await uploadString(ref, dataUrl, 'data_url');
const url = await getDownloadURL(ref);
return url;
} finally {
setIsUploadingImage(false);
}
}
async function onSubmitCreateService() {
if (!userIdentifier) {
Alert.alert('Non connecté', 'Connecte-toi pour créer un service.');
return;
}
if (!isFormValid) {
Alert.alert('Champs manquants', 'Merci de remplir tous les champs requis.');
return;
}
setIsSavingService(true);
try {
const now = serverTimestamp();
const categoryReference = doc(firestoreDatabase, 'categories', selectedCategory.id);
// Téléversement de l’image si présente
let imageUrl = null;
if (localImageUri) {
imageUrl = await uploadImageAndGetUrl(localImageUri, userIdentifier);
}
// Création DANS la sous-collection workers/{userIdentifier}/services
await addDoc(collection(firestoreDatabase, 'workers', userIdentifier, 'services'), {
name: serviceName.trim(),
price: Number(servicePrice),
hours: Number(serviceHours) || 0,
minutes: Number(serviceMinutes) || 0,
image: imageUrl,
category: categoryReference,
visible: true,
createdAt: now,
updatedAt: now,
});
navigation.goBack();
} catch (error) {
console.log('onSubmitCreateService error', error);
Alert.alert('Erreur', 'Impossible de créer le service.');
} finally {
setIsSavingService(false);
}
}
if (!isAuthReady) return null;
if (isAuthReady && !userIdentifier) {
return (
Connecte-toi.
);
}
return (
Nouveau service
{/* Image */}
Image
{localImageUri ? (
Changer l’image
Supprimer
) : (
Ajouter une image
)}
{isUploadingImage && Téléversement…}
{/* Nom */}
Nom *
{/* Catégorie */}
Catégorie *
setIsCategoryDropdownOpen((v) => !v)}>
{selectedCategory ? selectedCategory.name : 'Choisir une catégorie'}
{isCategoryDropdownOpen && (
{categoriesList.map((category) => (
{
setSelectedCategory({ id: category.id, name: category.name });
setIsCategoryDropdownOpen(false);
}}
>
{category.name}
))}
)}
{/* Prix et durée */}
Prix ($) *
Heures *
Minutes *
{!isFormValid && * Champs obligatoires}
{isSavingService ? (
) : (
Créer
)}
navigation.goBack()}>
Annuler
);
}
const styles = StyleSheet.create({
center: { flex: 1, alignItems: 'center', justifyContent: 'center' },
screen: { padding: 16, marginTop: 36 },
title: { fontSize: 24, fontWeight: '800', color: '#111111', marginBottom: 12 },
field: { marginBottom: 12 },
label: { fontSize: 13, color: MUTED_TEXT_COLOR, marginBottom: 6 },
input: {
borderWidth: 1,
borderColor: 'rgba(43,30,18,0.18)',
borderRadius: 12,
paddingHorizontal: 14,
height: 48,
backgroundColor: '#ffffff',
},
// Image
pickButton: {
flexDirection: 'row',
alignItems: 'center',
gap: 8,
borderWidth: 1,
borderColor: 'rgba(43,30,18,0.18)',
borderRadius: 12,
paddingHorizontal: 14,
height: 48,
backgroundColor: '#ffffff',
},
pickButtonText: { color: '#222222', fontWeight: '600' },
imageRow: { flexDirection: 'row', alignItems: 'center', gap: 12 },
preview: { width: 96, height: 96, borderRadius: 12, backgroundColor: '#eeeeee' },
lightButton: {
flexDirection: 'row',
alignItems: 'center',
gap: 6,
backgroundColor: '#eeeeee',
borderRadius: 12,
paddingVertical: 10,
paddingHorizontal: 12,
borderWidth: 1,
borderColor: '#e2e2e2',
},
lightButtonText: { color: '#222222', fontWeight: '700' },
// Sélecteur catégorie
select: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
borderWidth: 1,
borderColor: 'rgba(43,30,18,0.18)',
borderRadius: 12,
paddingHorizontal: 14,
height: 48,
backgroundColor: '#ffffff',
},
selectText: { color: '#222222' },
selectList: {
backgroundColor: '#ffffff',
borderRadius: 12,
marginTop: 6,
borderWidth: 1,
borderColor: '#e9e9e9',
},
selectItem: { paddingVertical: 12, paddingHorizontal: 12 },
selectItemText: { fontSize: 16, color: '#111111' },
row: { flexDirection: 'row', alignItems: 'flex-start' },
hint: { color: MUTED_TEXT_COLOR, marginBottom: 8 },
primaryButton: {
backgroundColor: PRIMARY_COLOR,
height: 52,
borderRadius: 14,
alignItems: 'center',
justifyContent: 'center',
marginTop: 6,
},
primaryButtonDisabled: { opacity: 0.6 },
primaryButtonText: { color: '#ffffff', fontSize: 16, fontWeight: '700' },
cancelButton: { alignSelf: 'center', marginTop: 10 },
cancelButtonText: { color: '#333333', fontWeight: '600' },
});
< /code>
При необходимости это мой пакет.json < /p>
{
"name": "beautify-worker",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web"
},
"dependencies": {
"@react-native-async-storage/async-storage": "2.1.2",
"@react-native-community/datetimepicker": "8.4.1",
"@react-navigation/bottom-tabs": "^7.4.6",
"@react-navigation/native": "^7.1.17",
"@react-navigation/native-stack": "^7.3.25",
"expo": "53.0.20",
"expo-auth-session": "~6.2.1",
"expo-file-system": "~18.1.11",
"expo-image-manipulator": "~13.1.7",
"expo-image-picker": "~16.1.4",
"expo-secure-store": "~14.2.3",
"expo-status-bar": "~2.2.3",
"expo-web-browser": "~14.2.0",
"firebase": "^12.1.0",
"react": "19.0.0",
"react-dom": "19.0.0",
"react-native": "0.79.5",
"react-native-dotenv": "^3.4.11",
"react-native-gesture-handler": "~2.24.0",
"react-native-google-places-autocomplete": "^2.5.7",
"react-native-reanimated": "~3.17.4",
"react-native-safe-area-context": "5.4.0",
"react-native-screens": "~4.11.1",
"react-native-url-polyfill": "^2.0.0",
"react-native-web": "^0.20.0"
},
"devDependencies": {
"@babel/core": "^7.20.0",
"@types/react": "~19.0.10",
"typescript": "~5.8.3"
},
"private": true
}
Подробнее здесь: https://stackoverflow.com/questions/797 ... are-not-su
Ошибка [Ошибка: Создание Blobs из «ArrayBuffer» и «ArrayBufferview» не поддерживается] ⇐ Javascript
Форум по Javascript
1756477068
Anonymous
Я пытаюсь загрузить изображения с моего устройства Galery в мое приложение React Native Expo с помощью Firebase, но я получаю ошибку OnSubmitCreatEService [Ошибка: создание каплей из «ArrayBuffer» и «ArrayBufferview» не поддерживается]. Может ли кто -нибудь помочь мне решить это, пожалуйста? Как только я загружаю изображение и проверяю форму < /p>
import React, { useEffect, useState } from 'react';
import {
View,
Text,
TextInput,
StyleSheet,
TouchableOpacity,
ActivityIndicator,
Alert,
ScrollView,
Pressable,
Image,
} from 'react-native';
import { Ionicons } from '@expo/vector-icons';
import * as ImagePicker from 'expo-image-picker';
import * as ImageManipulator from 'expo-image-manipulator';
import * as FileSystem from 'expo-file-system';
import { auth as firebaseAuth, db as firestoreDatabase, storage as firebaseStorage } from '../FirebaseConfig';
import {
addDoc,
collection,
doc,
onSnapshot,
orderBy,
query,
serverTimestamp,
} from 'firebase/firestore';
import { onAuthStateChanged } from 'firebase/auth';
import { ref as createStorageRef, uploadString, getDownloadURL } from 'firebase/storage';
const PRIMARY_COLOR = '#2B1E12';
const MUTED_TEXT_COLOR = '#6b6b6b';
export default function AddNewService({ navigation }) {
const [userIdentifier, setUserIdentifier] = useState(null);
const [isAuthReady, setIsAuthReady] = useState(false);
useEffect(() => {
return onAuthStateChanged(firebaseAuth, (user) => {
setUserIdentifier(user?.uid ?? null);
setIsAuthReady(true);
});
}, []);
// Formulaire
const [serviceName, setServiceName] = useState('');
const [servicePrice, setServicePrice] = useState('');
const [serviceHours, setServiceHours] = useState('0');
const [serviceMinutes, setServiceMinutes] = useState('30');
// Catégories
const [categoriesList, setCategoriesList] = useState([]);
const [isCategoryDropdownOpen, setIsCategoryDropdownOpen] = useState(false);
const [selectedCategory, setSelectedCategory] = useState(null); // { id, name }
// Image locale + téléversement
const [localImageUri, setLocalImageUri] = useState(null);
const [isUploadingImage, setIsUploadingImage] = useState(false);
const [isSavingService, setIsSavingService] = useState(false);
const isFormValid =
serviceName.trim() &&
selectedCategory &&
servicePrice !== '' &&
serviceHours !== '' &&
serviceMinutes !== '';
// Charger la liste des catégories
useEffect(() => {
const categoriesQuery = query(collection(firestoreDatabase, 'categories'), orderBy('name', 'asc'));
const unsubscribe = onSnapshot(categoriesQuery, (snapshot) => {
setCategoriesList(snapshot.docs.map((d) => ({ id: d.id, ...d.data() })));
});
return unsubscribe;
}, []);
async function requestMediaLibraryPermission() {
const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
if (status !== 'granted') throw new Error('Permission refusée');
}
async function pickImageFromLibrary() {
try {
await requestMediaLibraryPermission();
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images,
allowsEditing: true,
quality: 0.9,
});
if (result.canceled) return;
const pickedAsset = result.assets[0];
// Redimensionner / compresser et forcer JPEG
const manipulatedImage = await ImageManipulator.manipulateAsync(
pickedAsset.uri,
[{ resize: { width: 1200 } }],
{ compress: 0.8, format: ImageManipulator.SaveFormat.JPEG }
);
// S’assurer d’un schéma file://
let fileUri = manipulatedImage.uri;
if (!fileUri.startsWith('file://')) {
const target = FileSystem.cacheDirectory + `service-${Date.now()}.jpg`;
await FileSystem.copyAsync({ from: fileUri, to: target });
fileUri = target;
}
setLocalImageUri(fileUri);
} catch (error) {
console.log('pickImageFromLibrary error', error);
Alert.alert('Image', 'Impossible d’ouvrir la galerie.');
}
}
function removeSelectedImage() {
setLocalImageUri(null);
}
async function uploadImageAndGetUrl(fileUri, workerId) {
setIsUploadingImage(true);
try {
const path = `services/${workerId}/${Date.now()}-${Math.random().toString(36).slice(2, 7)}.jpg`;
const base64 = await FileSystem.readAsStringAsync(fileUri, { encoding: FileSystem.EncodingType.Base64 });
const ref = createStorageRef(firebaseStorage, path);
const dataUrl = `data:image/jpeg;base64,${base64}`;
await uploadString(ref, dataUrl, 'data_url');
const url = await getDownloadURL(ref);
return url;
} finally {
setIsUploadingImage(false);
}
}
async function onSubmitCreateService() {
if (!userIdentifier) {
Alert.alert('Non connecté', 'Connecte-toi pour créer un service.');
return;
}
if (!isFormValid) {
Alert.alert('Champs manquants', 'Merci de remplir tous les champs requis.');
return;
}
setIsSavingService(true);
try {
const now = serverTimestamp();
const categoryReference = doc(firestoreDatabase, 'categories', selectedCategory.id);
// Téléversement de l’image si présente
let imageUrl = null;
if (localImageUri) {
imageUrl = await uploadImageAndGetUrl(localImageUri, userIdentifier);
}
// Création DANS la sous-collection workers/{userIdentifier}/services
await addDoc(collection(firestoreDatabase, 'workers', userIdentifier, 'services'), {
name: serviceName.trim(),
price: Number(servicePrice),
hours: Number(serviceHours) || 0,
minutes: Number(serviceMinutes) || 0,
image: imageUrl,
category: categoryReference,
visible: true,
createdAt: now,
updatedAt: now,
});
navigation.goBack();
} catch (error) {
console.log('onSubmitCreateService error', error);
Alert.alert('Erreur', 'Impossible de créer le service.');
} finally {
setIsSavingService(false);
}
}
if (!isAuthReady) return null;
if (isAuthReady && !userIdentifier) {
return (
Connecte-toi.
);
}
return (
Nouveau service
{/* Image */}
Image
{localImageUri ? (
Changer l’image
Supprimer
) : (
Ajouter une image
)}
{isUploadingImage && Téléversement…}
{/* Nom */}
Nom *
{/* Catégorie */}
Catégorie *
setIsCategoryDropdownOpen((v) => !v)}>
{selectedCategory ? selectedCategory.name : 'Choisir une catégorie'}
{isCategoryDropdownOpen && (
{categoriesList.map((category) => (
{
setSelectedCategory({ id: category.id, name: category.name });
setIsCategoryDropdownOpen(false);
}}
>
{category.name}
))}
)}
{/* Prix et durée */}
Prix ($) *
Heures *
Minutes *
{!isFormValid && * Champs obligatoires}
{isSavingService ? (
) : (
Créer
)}
navigation.goBack()}>
Annuler
);
}
const styles = StyleSheet.create({
center: { flex: 1, alignItems: 'center', justifyContent: 'center' },
screen: { padding: 16, marginTop: 36 },
title: { fontSize: 24, fontWeight: '800', color: '#111111', marginBottom: 12 },
field: { marginBottom: 12 },
label: { fontSize: 13, color: MUTED_TEXT_COLOR, marginBottom: 6 },
input: {
borderWidth: 1,
borderColor: 'rgba(43,30,18,0.18)',
borderRadius: 12,
paddingHorizontal: 14,
height: 48,
backgroundColor: '#ffffff',
},
// Image
pickButton: {
flexDirection: 'row',
alignItems: 'center',
gap: 8,
borderWidth: 1,
borderColor: 'rgba(43,30,18,0.18)',
borderRadius: 12,
paddingHorizontal: 14,
height: 48,
backgroundColor: '#ffffff',
},
pickButtonText: { color: '#222222', fontWeight: '600' },
imageRow: { flexDirection: 'row', alignItems: 'center', gap: 12 },
preview: { width: 96, height: 96, borderRadius: 12, backgroundColor: '#eeeeee' },
lightButton: {
flexDirection: 'row',
alignItems: 'center',
gap: 6,
backgroundColor: '#eeeeee',
borderRadius: 12,
paddingVertical: 10,
paddingHorizontal: 12,
borderWidth: 1,
borderColor: '#e2e2e2',
},
lightButtonText: { color: '#222222', fontWeight: '700' },
// Sélecteur catégorie
select: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
borderWidth: 1,
borderColor: 'rgba(43,30,18,0.18)',
borderRadius: 12,
paddingHorizontal: 14,
height: 48,
backgroundColor: '#ffffff',
},
selectText: { color: '#222222' },
selectList: {
backgroundColor: '#ffffff',
borderRadius: 12,
marginTop: 6,
borderWidth: 1,
borderColor: '#e9e9e9',
},
selectItem: { paddingVertical: 12, paddingHorizontal: 12 },
selectItemText: { fontSize: 16, color: '#111111' },
row: { flexDirection: 'row', alignItems: 'flex-start' },
hint: { color: MUTED_TEXT_COLOR, marginBottom: 8 },
primaryButton: {
backgroundColor: PRIMARY_COLOR,
height: 52,
borderRadius: 14,
alignItems: 'center',
justifyContent: 'center',
marginTop: 6,
},
primaryButtonDisabled: { opacity: 0.6 },
primaryButtonText: { color: '#ffffff', fontSize: 16, fontWeight: '700' },
cancelButton: { alignSelf: 'center', marginTop: 10 },
cancelButtonText: { color: '#333333', fontWeight: '600' },
});
< /code>
При необходимости это мой пакет.json < /p>
{
"name": "beautify-worker",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web"
},
"dependencies": {
"@react-native-async-storage/async-storage": "2.1.2",
"@react-native-community/datetimepicker": "8.4.1",
"@react-navigation/bottom-tabs": "^7.4.6",
"@react-navigation/native": "^7.1.17",
"@react-navigation/native-stack": "^7.3.25",
"expo": "53.0.20",
"expo-auth-session": "~6.2.1",
"expo-file-system": "~18.1.11",
"expo-image-manipulator": "~13.1.7",
"expo-image-picker": "~16.1.4",
"expo-secure-store": "~14.2.3",
"expo-status-bar": "~2.2.3",
"expo-web-browser": "~14.2.0",
"firebase": "^12.1.0",
"react": "19.0.0",
"react-dom": "19.0.0",
"react-native": "0.79.5",
"react-native-dotenv": "^3.4.11",
"react-native-gesture-handler": "~2.24.0",
"react-native-google-places-autocomplete": "^2.5.7",
"react-native-reanimated": "~3.17.4",
"react-native-safe-area-context": "5.4.0",
"react-native-screens": "~4.11.1",
"react-native-url-polyfill": "^2.0.0",
"react-native-web": "^0.20.0"
},
"devDependencies": {
"@babel/core": "^7.20.0",
"@types/react": "~19.0.10",
"typescript": "~5.8.3"
},
"private": true
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79749907/error-error-creating-blobs-from-arraybuffer-and-arraybufferview-are-not-su[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия