React Native expo 图像选择器将图像上传到 firebase 存储(v9)崩溃

React Native expo image picker upload image to firebase storage (v9) crash

我正在尝试将从 expo 图像选择器中选择的图像上传到 firebase 存储(因为我使用的是 expo)。 我检查了 expo 图像选择器 git 并找到了 uploadImageAsync for firebase。 所以我复制了它,只做了一点改动,但不知何故,它大部分时间都会让应用程序崩溃。只有几次,它正确上传了图像,没有任何错误。

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);
}

由于uri来自phone中的图片,uri = file:///Users/~绝对路径~/imagename.jpg 这是 firebase 的 link expo 图像选择器 expo image picker for firebase

问题报告说, 以 NSException 类型的未捕获异常终止 由于未捕获的异常 'NSInvalidArgumentException',正在终止应用程序,原因:' -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]:尝试从 objects[0]'

中插入 nil 对象

edit) 我发现它在 android 中有效,但在 ios 中无效 对于 IOS,我认为转换为 blob 是可行的。但有错误 const result = await uploadBytes(fileRef, blob)

我也遇到了同样的问题,在firebase 9.6.5版本上,所以我用函数uploadBytesResumable代替了uploadBytes,效果很好,如果紧急可以暂时使用那个函数,只是一个建议,供参考:- https://firebase.google.com/docs/storage/web/upload-files

我只在 iOS 15 和 15 + 时遇到过这个问题,在 iOS 15 以下并且在 android 应用程序中 uploadBytes 工作正常。

注意:- 将 XMLHttpRequest 与 uploadBytesResumable 一起使用时,第一次在 iOS 15.2 上顺利上传图片,然后在第二次上传图片时出现崩溃。为避免使用, const img = await fetch(image_url); const blob = await 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
   });
});