Search code examples
laravelamazon-s3laravel-nova

Download files stored in AWS S3 from Laravel Nova results in bug


We are using Nova package for our admin backend inside our Laravel App. All files and images are stored in the AWS S3 bucket.

After trying to download a file from Nova, the download begins with the name download.json and Server Error message.

Files are stored correctly in S3, I can check it manually, also the path to them inside S3 is correctly stored in the database.

Here is the code we use to create a download field in Nova

                ->download(function(){
                    return Storage::disk('s3')->download($this->name);
                })
                ->onlyOnDetail()

$this->name holds the path inside the s3 bucket.

config/filesystems.php is also defined:

'disks' => [
         ...
        's3' => [
            'driver' => 's3',
            'key' => env('AWS_ACCESS_KEY_ID'),
            'secret' => env('AWS_SECRET_ACCESS_KEY'),
            'region' => env('AWS_DEFAULT_REGION'),
            'bucket' => env('AWS_BUCKET'),
            'url' => env('AWS_URL'),
        ],

Nova documentation did not helped me on this problem. Any input would be really helpful.

UPDATE: The problem was not in code but in Configuration. Without changing the configuration the following code did help:

Text::make('File/Document', function() {
                $linkToFile = Storage::disk('s3')->temporaryUrl($this->name, now()->addMinutes(1));
                return '<a href="' . $linkToFile . '" target="_blank">Download file</a>';
            })
                ->asHtml(),

Solution

  • Hard to see any issue without seeing the complete function, but make sure your name property $this->name has the same value as your remote file 'key' as shown in your Amazon s3 bucket.

    Also, make sure the your .env file is correct and contains the following value:

    AWS_ACCESS_KEY_ID=your_access_key
    AWS_SECRET_ACCESS_KEY=your_secret_access_key
    AWS_DEFAULT_REGION=your_default_region
    AWS_BUCKET=your_bucket_name
    AWS_URL=your_url #if applicable
    

    Hope this makes sense.


    Edit: One more thing, in filesystem.php, this line:

      'url' => env('AWS_URL'),
    

    was changed in Laravel 6.x according to this bug and became:

      'endpoint' => env('AWS_URL'),