Amplify v6 uploadData: 在 React Native Expo 中上传文件时出现 [AccessDenied: Access Denied] 错误

问题描述 投票:0回答:1

我正在使用 Expo 和 AWS Amplify 将我的 React Native 应用程序从版本 5 迁移到版本 6。我在尝试使用 uploadData 方法将文件上传到 S3 时遇到 AccessDenied:访问被拒绝错误。

这是我的版本 5 的代码,运行良好:

import * as ImageManipulator from 'expo-image-manipulator';
import { Storage } from 'aws-amplify';
import uuid from 'react-native-uuid';

export async function uploadImage(uri: string): Promise<string | null> {
  try {
    if (!uri) {
      throw new Error('Invalid URI provided for uploading the image');
    }
    const id = uuid.v4().toString();  // Generate a version 4 UUID
    const response = await fetch(uri);
    if (!response.ok && response.type !== 'default') {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    const blob = await response.blob();
    if (!blob) {
      throw new Error('Failed to convert the response to a blob');
    }
    const result = await Storage.put(id, blob);
    if (!result.key) {
      throw new Error('Failed to upload the image');
    }
    return result.key;
  } catch (err) {
    console.error('Error uploading file: ', err);
    return null;
  }
}

这是我的版本 6 的代码,它给出了 AccessDenied 错误:

import { getUrl, uploadData } from 'aws-amplify/storage';

export async function uploadImage(uri: string): Promise<string | null> {
  try {
    if (!uri) {
      throw new Error('Invalid URI provided for uploading the image');
    }
    const id = uuid.v4().toString();  // Generate a version 4 UUID
    const response = await fetch(uri);
    if (!response.ok && response.type !== 'default') {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    const blob = await response.blob();
    if (!blob) {
      throw new Error('Failed to convert the response to a blob');
    }
    console.log('id', id);
    console.log('blob', blob);
    const operation = uploadData({ path: id, data: blob })
    const result = await operation.result
    console.log('result', result);
    if (!result.path) {
      throw new Error('Failed to upload the image');
    }
    return result.path;
  } catch (err) {
    console.error('Error uploading file: ', err);
    return null;
  }
}

错误信息是:

Error uploading file: [AccessDenied: Access Denied]

据我了解,该问题可能与 uploadData 中使用的路径有关。我应该如何正确指定路径或设置访问级别来修复此错误?

react-native aws-amplify
1个回答
0
投票

从 Amplify v5 迁移到 v6 时,S3 上传的路径和访问级别的管理方式发生了一些变化。在 v6 中,您需要在路径中显式指定访问级别。

这是 v6 的更正代码:

import { uploadData } from 'aws-amplify/storage';
import uuid from 'react-native-uuid';

export async function uploadImage(uri: string): Promise<string | null> {
  try {
    if (!uri) {
      throw new Error('Invalid URI provided for uploading the image');
    }
    const id = uuid.v4().toString();  // Generate a version 4 UUID
    const response = await fetch(uri);
    if (!response.ok && response.type !== 'default') {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    const blob = await response.blob();
    if (!blob) {
      throw new Error('Failed to convert the response to a blob');
    }
    console.log('id', id);
    console.log('blob', blob);
    const operation = uploadData({ path: `public/${id}`, data: blob })  // Specify the public access level in the path
    const result = await operation.result
    console.log('result', result);
    if (!result.path) {
      throw new Error('Failed to upload the image');
    }
    return result.path;
  } catch (err) {
    console.error('Error uploading file: ', err);
    return null;
  }
}

说明: 路径中的访问级别: 在 v6 中,您需要在 uploadData 方法的路径中指定访问级别。默认情况下,访问级别设置为 public,但您需要将其显式包含在路径中,例如 public/{id}。

文档参考: 根据 Amplify 文档,路径必须包含访问级别前缀:

公开:您的应用程序的所有用户都可以访问。文件存储在 S3 存储桶中的 public/ 路径下。 受保护:所有用户均可读取,但仅创建用户可写入。文件存储在 protected/{user_identity_id}/ 下。 私有:仅供个人用户访问。文件存储在 private/{user_identity_id}/ 下。 参考资料:

此更改应该可以解决您遇到的 AccessDenied 错误。如果您还有其他问题,请确保正确配置您的 IAM 策略和 S3 存储桶策略以允许必要的权限。

© www.soinside.com 2019 - 2024. All rights reserved.