'Laravel Jetstream livewire - Profile photo is not being uploaded on s3

I have checked everything in AWS S3, permissions, policy bucket name, all looks okay. I have updated the config in the jetstream config file

config\jetstream.php


'profile_photo_disk' => 's3',

I have updated the .env file variables with AWS S3 values, but the profile photo has not been uploaded on S3.

The same credentials are working on simple Laravel upload code, the image is successfully uploaded on s3, but by using Jetstream, it is not working, also there is no error reflected on the screen and in the log file as well.

Anyone could please help



Solution 1:[1]

There is a function written in the library trait, path and function is as below

Path: \vendor\laravel\jetstrem\src\HasProfilePhoto.php

Function:

/**
 * Update the user's profile photo.
 *
 * @param  \Illuminate\Http\UploadedFile  $photo
 * @return void
 */
public function updateProfilePhoto(UploadedFile $photo)
{
    tap($this->profile_photo_path, function ($previous) use ($photo) {
        $this->forceFill([
            'profile_photo_path' => $photo->storePublicly(
                'profile-photos', ['disk' => $this->profilePhotoDisk()]
            ),
        ])->save();

        if ($previous) {
            Storage::disk($this->profilePhotoDisk())->delete($previous);
        }
    });
}

As you can see for uploading the profile image on s3 the function used is storePublicly, but in my case, the s3 policy is not defined as publicly read, so I have overloaded the same function in

app\Actions\Fortify\UpdateUserProfileInformation.php

On top of the class add the Trait as use HasProfilePhoto;

/**
 * Update the user's profile photo.
 *
 * @param  \Illuminate\Http\UploadedFile  $photo
 * @return void
 * 
 * 
 */
public function updateProfilePhoto($user, UploadedFile $photo)
{
    tap($user->profile_photo_path, function ($previous) use ($photo, $user) {
        $user->forceFill([
            'profile_photo_path' => $photo->store(
                'profile-photos', ['disk' => config('jetstream.profile_photo_disk')]
            ),
        ])->save();

        if ($previous) {
            \Storage::disk(config('jetstream.profile_photo_disk'))->delete($previous);
        }
    });
}

This works for me, I hope if you face similar issue, then it would help you.

Solution 2:[2]

The problem is related to the CORS policy on the S3 bucket.

I overwrote to use ->store(...) instead of ->storePublicly(...), which solved my issue.

Original:

public function updateProfilePhoto(UploadedFile $photo)
    {
        tap($this->profile_photo_path, function ($previous) use ($photo) {
            $this->forceFill([
                'profile_photo_path' => $photo->storePublicly(
                    'profile-photos', ['disk' => $this->profilePhotoDisk()]
                ),
            ])->save();

            if ($previous) {
                Storage::disk($this->profilePhotoDisk())->delete($previous);
            }
        });
    }

New:

 public function updateProfilePhoto(UploadedFile $photo)
    {
        tap($this->profile_photo_path, function ($previous) use ($photo) {
            $this->forceFill([
                'profile_photo_path' => $photo->store(
                    'profile-photos', ['disk' => $this->profilePhotoDisk()]
                ),
            ])->save();

            if ($previous) {
                Storage::disk($this->profilePhotoDisk())->delete($previous);
            }
        });
    }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Mahesh Yadav
Solution 2 user3092080