带有轨道API的Expo Image Picker获取Errno :: Enoent(没有此类文件或目录 @ rb_sysopen

发布于 2025-02-08 02:17:21 字数 3089 浏览 2 评论 0原文

当我尝试通过Expo的图像上传:ImagePicker时,我会得到:

Completed 500 Internal Server Error in 1ms (ActiveRecord: 2.8ms | Allocations: 637)
  
Errno::ENOENT (No such file or directory @ rb_sysopen - file:///data/user/0/host.exp.exponent/cache/ExperienceData/%2540zilasino%252Frestaurant-management/ImagePicker/5f29f45c-4467-4360-bcc8-2651146837b3.jpg):

当我通过失眠点击端点时,它确实可以正常工作时,图像已上传,但是通过在Android模拟器上运行的Expo应用程序可以执行此操作。似乎,数据传递给了铁轨,但是由于某种原因,铁轨无法找到该文件...有什么想法吗?

createMenuitem.js

const addMenuItem = async () => {
    const menuItem = {
      name,
      price,
      image: selectedImage.uri,
      is_drink: isDrink ? true : false,
      notes,
    };
   const resp = await createAccessory("menu_items", menuItem);
    if(resp.type == 'success'){
      fetchMenuItemData();
      clearFields()
    }
    showMessage({
      message: `${resp.msg}`,
      position: "center",
      duration: 2500,
      style: { backgroundColor: resp.type == 'success' ? colors.PRIMARY : colors.ERROR },
      titleStyle: { fontSize: 20 },
    });
  };


const createAccessory = async (accessory, payload) => {
    return await axios.post(baseUrl + '/' + accessory, payload, {headers})
    .then(resp => {
        if (resp.data){
            return { msg: i18n.t('saved'), type: 'success' }
        } })
        .catch(error => {
            if (error.response) {
            return { msg: error.response.data.name }
        }
      }
    )
}

imageupload.js

const ImageUpload = ({ parentCallback, selectedImage }) => {
  let openImagePickerAsync = async () => {
    let permissionResult =
      await ImagePicker.requestMediaLibraryPermissionsAsync();

    if (permissionResult.granted === false) {
      alert("Permission to access camera roll is required!");
      return;
    }

    let pickerResult = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.Images,
      allowsEditing: true,
      aspect: [1, 1],
      quality: 1
    });

    if (pickerResult.cancelled === true) {
      return;
    }
    parentCallback(pickerResult);
  };

  if (selectedImage != null) {
    return (
      <>
        <Image
          source={{ uri: selectedImage.uri }}
          style={styles.thumbnail}
          resizeMode="contain"
        />
        <Button
          title="X"
          color={colors.PRIMARY}
          onPress={() => parentCallback(null)}
        />
      </>
    );
  } else {
    return (
      <>
        <TouchableOpacity onPress={openImagePickerAsync} style={styles.button}>
          <Text style={styles.buttonText}>{i18n.t("pickAnImage")}</Text>
        </TouchableOpacity>
      </>
    );
  }
};

Controller.rb

    class MenuItemsController < ApplicationController
     ...
      def create
        image = Cloudinary::Uploader.upload(params[:image])
        menu_item = MenuItem.new(
          image: image['url'],
        )
      end 
   ...
   end

When I try to upload image via Expo's: ImagePicker I get:

Completed 500 Internal Server Error in 1ms (ActiveRecord: 2.8ms | Allocations: 637)
  
Errno::ENOENT (No such file or directory @ rb_sysopen - file:///data/user/0/host.exp.exponent/cache/ExperienceData/%2540zilasino%252Frestaurant-management/ImagePicker/5f29f45c-4467-4360-bcc8-2651146837b3.jpg):

It does work fine when I hit the endpoint via Insomnia, the image is uploaded, but it doesn't work doing so via expo app running on Android Emulator. It seems like, the data is passing to rails, but for some reason rails is unable to find that file... Any ideas?

CreateMenuItem.js

const addMenuItem = async () => {
    const menuItem = {
      name,
      price,
      image: selectedImage.uri,
      is_drink: isDrink ? true : false,
      notes,
    };
   const resp = await createAccessory("menu_items", menuItem);
    if(resp.type == 'success'){
      fetchMenuItemData();
      clearFields()
    }
    showMessage({
      message: `${resp.msg}`,
      position: "center",
      duration: 2500,
      style: { backgroundColor: resp.type == 'success' ? colors.PRIMARY : colors.ERROR },
      titleStyle: { fontSize: 20 },
    });
  };


const createAccessory = async (accessory, payload) => {
    return await axios.post(baseUrl + '/' + accessory, payload, {headers})
    .then(resp => {
        if (resp.data){
            return { msg: i18n.t('saved'), type: 'success' }
        } })
        .catch(error => {
            if (error.response) {
            return { msg: error.response.data.name }
        }
      }
    )
}

ImageUpload.js

const ImageUpload = ({ parentCallback, selectedImage }) => {
  let openImagePickerAsync = async () => {
    let permissionResult =
      await ImagePicker.requestMediaLibraryPermissionsAsync();

    if (permissionResult.granted === false) {
      alert("Permission to access camera roll is required!");
      return;
    }

    let pickerResult = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.Images,
      allowsEditing: true,
      aspect: [1, 1],
      quality: 1
    });

    if (pickerResult.cancelled === true) {
      return;
    }
    parentCallback(pickerResult);
  };

  if (selectedImage != null) {
    return (
      <>
        <Image
          source={{ uri: selectedImage.uri }}
          style={styles.thumbnail}
          resizeMode="contain"
        />
        <Button
          title="X"
          color={colors.PRIMARY}
          onPress={() => parentCallback(null)}
        />
      </>
    );
  } else {
    return (
      <>
        <TouchableOpacity onPress={openImagePickerAsync} style={styles.button}>
          <Text style={styles.buttonText}>{i18n.t("pickAnImage")}</Text>
        </TouchableOpacity>
      </>
    );
  }
};

controller.rb

    class MenuItemsController < ApplicationController
     ...
      def create
        image = Cloudinary::Uploader.upload(params[:image])
        menu_item = MenuItem.new(
          image: image['url'],
        )
      end 
   ...
   end

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

ゝ偶尔ゞ 2025-02-15 02:17:21

一个可能的问题是,通往图像文件的路径不正确。尝试仔细检查路径,并确保图像文件位于正确的位置。

One possible issue could be that the path to the image file is incorrect. Try double-checking the path and make sure that the image file is in the correct location.

哀由 2025-02-15 02:17:21

我弄清楚了,我不得不将图像作为base64而不仅仅是它的URI传递给Rails。

我刚刚添加了base64:true选项:

    let pickerResult = await ImagePicker.launchCameraAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.Images,
      allowsEditing: true,
      aspect: [1, 1],
      quality: 1,
      base64: true
    })

并像这样更改Rails Controller中的一行:

image = Cloudinary::Uploader.upload('data:image/jpeg;base64,' + menu_item_params[:image])

I figured it out, I had to pass the image to Rails as a Base64 and not just its URI.

I've just added base64: true option:

    let pickerResult = await ImagePicker.launchCameraAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.Images,
      allowsEditing: true,
      aspect: [1, 1],
      quality: 1,
      base64: true
    })

and change one line in rails controller like so:

image = Cloudinary::Uploader.upload('data:image/jpeg;base64,' + menu_item_params[:image])

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文