aws-amplify / amplify-flutter

A declarative library with an easy-to-use interface for building Flutter applications on AWS.
https://docs.amplify.aws
Apache License 2.0
1.33k stars 247 forks source link

S3. Cannot find the item specified by the provided path #5601

Open Dapucla opened 1 month ago

Dapucla commented 1 month ago

Description

Simply after uploadImage() function gets triggered and you select actually existing image with path. Error appears - "Cannot find the item specified by the provided path"

amplify/storage/resource.ts

import { defineStorage } from '@aws-amplify/backend';

export const storage = defineStorage({
  name: "mediafiles",
  access: (allow) => ({
    "media/public/{entity_id}/": [
      allow.guest.to(["read]"]),
      allow.entity("identity").to(["read", "write", "delete"]),
      allow.groups(["Admins"]).to(["read", "write", "delete"]),
    ],
    "media/protected/{entity_id}/": [
      allow.authenticated.to(["read"]),
      allow.entity("identity").to(["read", "write", "delete"]),
    ],
    "media/private/{entity_id}/*": [
      allow.entity("identity").to(["read", "write", "delete"]),
    ],
  }),
});
amplify/backend.ts

import { defineBackend } from '@aws-amplify/backend';
import { auth } from './auth/resource';
import { data } from './data/resource';
import { storage } from './storage/resource';
import { myFirstFunction } from './my-first-function/resource';

/**
 * @see https://docs.amplify.aws/react/build-a-backend/ to add storage, functions, and more
 */
const backend = defineBackend({
  auth,
  data,
  storage,
  myFirstFunction
});

// extract L1 UserPool construct
const { cfnUserPool } = backend.auth.resources.cfnResources;
// from the CDK use `addPropertyOverride` to modify properties directly
cfnUserPool.addPropertyOverride('Policies.PasswordPolicy.RequireUppercase', false);
cfnUserPool.addPropertyOverride('Policies.PasswordPolicy.RequireNumbers', false);
cfnUserPool.addPropertyOverride('Policies.PasswordPolicy.RequireSymbols', false);
Future<void> uploadImage() async {
    // Select a file from the device
    final result = await FilePicker.platform.pickFiles(
      type: FileType.custom,
      withData: false,
      // Ensure to get file stream for better performance
      withReadStream: true,
      allowedExtensions: ['jpg', 'png', 'gif'],
    );

    if (result == null) {
      safePrint('No file selected');
      return;
    }

    // Upload file using the filename
    final platformFile = result.files.single;
    try {
      final result = await Amplify.Storage.uploadFile(
        localFile: AWSFile.fromStream(
          platformFile.readStream!,
          size: platformFile.size,
        ),
        path: StoragePath.fromIdentityId((id) => "media/public/$id/${platformFile.name}"),
        onProgress: (progress) {
          safePrint('Fraction completed: ${progress.fractionCompleted}');
        },
      ).result;
      safePrint('Successfully uploaded file: ${result.uploadedItem.path}');
    } on StorageException catch (e) {
      safePrint(e.message);
    }
  }

flutter: -->      Subscription established
flutter: Fraction completed: 0.6744884936807871
flutter: Fraction completed: 1.0
flutter: Fraction completed: 1.0
flutter: Fraction completed: 1.0
flutter: Cannot find the item specified by the provided path.

Categories

Steps to Reproduce

Simply trigger uploadImage() function, during which after selecting image terminal states -

flutter: Cannot find the item specified by the provided path.

Screenshots

No response

Platforms

Flutter Version

3.24.0

Amplify Flutter Version

2.4.0

Deployment Method

Amplify Gen 2

Schema

No response

khatruong2009 commented 1 month ago

Hi @Dapucla, thank you for creating this issue. We will investigate this issue and get back to you with any questions or updates.

tyllark commented 2 weeks ago

Hello @Dapucla Sorry for the delay. I was not able to reproduce the issue you described as I receive flutter: Successfully uploaded file: media/public/... when running your uploadImage function. I needed to modify your amplify/storage/resource.ts file in order to generate my AmplifyOutputs. Can you please try updating your storage file to:

import { defineStorage } from '@aws-amplify/backend';

export const storage = defineStorage({
  name: "mediafiles",
  access: (allow) => ({
    "media/public/{entity_id}/*": [
      allow.guest.to(["read"]),
      allow.entity("identity").to(["read", "write", "delete"]),
      allow.groups(["Admins"]).to(["read", "write", "delete"]),
    ],
    "media/protected/{entity_id}/*": [
      allow.authenticated.to(["read"]),
      allow.entity("identity").to(["read", "write", "delete"]),
    ],
    "media/private/{entity_id}/*": [
      allow.entity("identity").to(["read", "write", "delete"]),
    ],
  }),
});

I didn't have an Admins group configured for my test, could you please provide your amplify/auth/resource.ts so I can recreate that.