Estoy tratando de cargar la imagen seleccionada del selector de imágenes de expo al almacenamiento de firebase (ya que estoy usando expo). Revisé expo image picker git y encontré uploadImageAsync para firebase. así que lo copié y cambié solo un poco, pero de alguna manera bloquea la aplicación la mayor parte del tiempo. Solo unas pocas veces, cargó la imagen correctamente sin ningún error.
import { storage } from '../firebase' async function uploadImageAsync(uri, name) { const blob = await new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); xhr.onload = function () { resolve(xhr.response); }; xhr.onerror = function (e) { console.log(e); reject(new TypeError("Network request failed")); }; xhr.responseType = "blob"; xhr.open("GET", uri, true); xhr.send(null); }); const fileRef = ref(storage, `files/${name}`); const result = await uploadBytes(fileRef, blob); // We're done with the blob, close and release it blob.close(); return await getDownloadURL(fileRef); }dado que el uri proviene de la imagen en el teléfono, uri = file:///Users/~absolute path ~/image name.jpg y este es el enlace expo image picker para firebase expo image picker para firebase
El informe del problema dice: Terminando con una excepción no detectada de tipo NSException Terminando la aplicación debido a una excepción no detectada 'NSInvalidArgumentException', motivo: ' -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: intento de insertar un objeto nulo de los objetos[0]'
editar) Descubrí que funciona en Android pero no en ios para IOS, creo que la conversión a blob está funcionando. pero tiene un error en el const result = await uploadBytes(fileRef, blob)
También enfrenté el mismo problema, en la versión 9.6.5 de firebase, así que utilicé la función uploadBytesResumable en lugar de uploadBytes, funciona bien, si es urgente, puede usar esa función por el momento, solo una recomendación, como referencia: - https://firebase.google.com/docs/storage/web/upload-files
Enfrenté este problema solo en iOS 15 y 15 +, descanse debajo de iOS 15 y en las aplicaciones de Android uploadBytes funciona bien.
Nota: al usar XMLHttpRequest con uploadBytesResumable, la primera vez que la imagen se carga sin problemas en iOS 15.2, luego, al cargarla por segunda vez, hay un bloqueo al cargar la imagen. Para evitarlo, utilice const img = await fetch(image_url); const blob = esperar img.blob();
import { getStorage, ref, getDownloadURL } from "firebase/storage"; const storageRef = ref(getStorage(), "image_name"); const img = await fetch(image_url); const blob = await img.blob(); console.log("uploading image"); const uploadTask = uploadBytesResumable(storageRef, blob); // Listen for state changes, errors, and completion of the upload. uploadTask.on('state_changed',(snapshot) => { // Get task progress, including the number of bytes uploaded and the total number of bytes to be uploaded const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100; console.log('Upload is ' + progress + '% done'); switch (snapshot.state) { case 'paused': console.log('Upload is paused'); break; case 'running': console.log('Upload is running'); break; } }, (error) => { this.setState({ isLoading: false }) // A full list of error codes is available at // https://firebase.google.com/docs/storage/web/handle-errors switch (error.code) { case 'storage/unauthorized': console.log("User doesn't have permission to access the object"); break; case 'storage/canceled': console.log("User canceled the upload"); break; case 'storage/unknown': console.log("Unknown error occurred, inspect error.serverResponse"); break; } }, () => { // Upload completed successfully, now we can get the download URL getDownloadURL(uploadTask.snapshot.ref).then((downloadURL) => { console.log('File available at', downloadURL); //perform your task }); });