Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Flysystem Google Cloud Storage Laravel Package

spatie/flysystem-google-cloud-storage

Google Cloud Storage adapter for Flysystem v1 (PHP 8). A maintained fork adding modern PHP support and merged fixes. Use it to connect Flysystem’s filesystem API to GCS with Google’s client authentication.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the package:
    composer require spatie/flysystem-google-cloud-storage
    
  2. Configure Google Cloud credentials:
    • Set up a Service Account in Google Cloud Console with "Storage Admin" permissions.
    • Download the JSON key file and store it securely (e.g., .env or Laravel's config/services.php):
      'google' => [
          'key' => env('GOOGLE_APPLICATION_CREDENTIALS_JSON'),
          'bucket' => env('GOOGLE_CLOUD_STORAGE_BUCKET'),
      ],
      
  3. Define a Flysystem adapter in config/filesystems.php:
    'disks' => [
        'gcs' => [
            'driver' => 'google',
            'key' => env('GOOGLE_APPLICATION_CREDENTIALS_JSON'),
            'bucket' => env('GOOGLE_CLOUD_STORAGE_BUCKET'),
            'project_id' => env('GOOGLE_CLOUD_PROJECT_ID'),
            'root' => env('GCS_ROOT_PATH', ''), // Optional: Prefix for all paths
        ],
    ],
    
  4. First use case: Upload a file via Laravel's Storage facade:
    use Illuminate\Support\Facades\Storage;
    
    Storage::disk('gcs')->put('path/to/file.txt', 'file contents');
    

Where to Look First


Implementation Patterns

Core Workflows

  1. File Operations:

    • Use Laravel's Storage facade or Flysystem's Filesystem directly:
      // Upload
      Storage::disk('gcs')->put('file.jpg', file_get_contents('local.jpg'));
      
      // Download
      $contents = Storage::disk('gcs')->get('file.jpg');
      
      // Delete
      Storage::disk('gcs')->delete('file.jpg');
      
    • Streaming large files:
      Storage::disk('gcs')->writeStream('large-file.zip', fopen('local.zip', 'r'));
      
  2. Directory Handling:

    • Create directories recursively:
      Storage::disk('gcs')->makeDirectory('folder/subfolder');
      
    • List files with optional prefix filtering:
      $files = Storage::disk('gcs')->files('folder/');
      
  3. Metadata and ACLs:

    • Set custom metadata:
      Storage::disk('gcs')->put('file.txt', 'content', [
          'metadata' => ['author' => 'John Doe'],
      ]);
      
    • Apply ACLs (requires google-cloud-storage v1.28+):
      Storage::disk('gcs')->put('file.txt', 'content', [
          'acl' => ['publicRead'],
      ]);
      

Integration Tips

  1. Laravel Filesystem Integration:

    • Use the disk in config/filesystems.php for seamless integration with:
      • Storage::disk('gcs')->url() (generates signed URLs if configured).
      • Storage::disk('gcs')->temporaryUrl() (for time-limited access).
    • Override default visibility:
      'visibility' => 'public', // or 'private'
      
  2. Customizing the Adapter:

    • Extend the adapter for project-specific logic:
      use Spatie\FlysystemGoogleCloudStorage\GoogleCloudStorageAdapter;
      
      class CustomGoogleAdapter extends GoogleCloudStorageAdapter {
          public function customMethod() {
              // ...
          }
      }
      
    • Register the custom adapter in config/filesystems.php:
      'gcs' => [
          'driver' => 'custom-google',
          'adapter' => CustomGoogleAdapter::class,
          // ...
      ],
      
  3. Environment-Specific Configs:

    • Use Laravel's config/caching or environment variables for multi-environment setups:
      'disks' => [
          'gcs_prod' => [
              'driver' => 'google',
              'key' => env('GOOGLE_PROD_KEY'),
              // ...
          ],
          'gcs_dev' => [
              'driver' => 'google',
              'key' => env('GOOGLE_DEV_KEY'),
              // ...
          ],
      ],
      
  4. Fallbacks and Retries:

    • Implement retry logic for transient failures (e.g., network issues):
      use Illuminate\Support\Facades\Storage;
      use Illuminate\Support\Str;
      
      $retry = 3;
      while ($retry--) {
          try {
              Storage::disk('gcs')->put('file.txt', 'content');
              break;
          } catch (\Exception $e) {
              if ($retry === 0) throw $e;
              sleep(Str::random(1) * 2); // Exponential backoff
          }
      }
      

Gotchas and Tips

Pitfalls

  1. Authentication Issues:

    • Error: Google\Auth\Exception\InvalidCredentialsException.
    • Cause: Invalid or expired JSON key file.
    • Fix:
      • Ensure the service account has "Storage Admin" permissions.
      • Verify the JSON key file path in .env or config/services.php.
      • Regenerate the key if corrupted.
  2. Bucket Permissions:

    • Error: Google\Cloud\Storage\StorageException: 403 Forbidden.
    • Cause: Bucket lacks storage.objects.create or storage.objects.delete permissions.
    • Fix:
      • Grant the service account explicit permissions in Google Cloud Console.
      • Use gsutil to test permissions:
        gsutil acl ch -u "service-account@project.iam.gserviceaccount.com" gs://bucket-name
        
  3. Path Handling:

    • Gotcha: GCS paths are case-sensitive and must match exactly.
    • Fix: Normalize paths before operations:
      $path = str_replace('\\', '/', trim($path, '/'));
      
  4. Visibility Defaults:

    • Gotcha: Files default to private unless explicitly set to public.
    • Fix: Configure default visibility in config/filesystems.php:
      'gcs' => [
          'driver' => 'google',
          'visibility' => 'public', // or 'private'
          // ...
      ],
      
  5. Large File Uploads:

    • Gotcha: Uploads >5MB may fail silently or timeout.
    • Fix:
      • Increase PHP max_execution_time and memory_limit.
      • Use chunked uploads:
        Storage::disk('gcs')->writeStream('large-file.zip', fopen('local.zip', 'r'), [
            'chunkSize' => 5 * 1024 * 1024, // 5MB chunks
        ]);
        

Debugging Tips

  1. Enable GCS Logging:

    • Set the GOOGLE_CLOUD_LOGGING environment variable to debug:
      export GOOGLE_CLOUD_LOGGING=debug
      
    • Check Laravel logs for Google\Cloud\Storage exceptions.
  2. Validate JSON Key:

    • Test the JSON key locally:
      gcloud auth activate-service-account --key-file=key.json
      gsutil ls gs://your-bucket-name
      
  3. Check Bucket Existence:

    • Ensure the bucket exists and is in the same region as your project:
      gsutil ls gs://your-bucket-name
      
  4. Network Restrictions:

    • If behind a proxy, configure the GOOGLE_CLOUD_PROXY environment variable:
      export GOOGLE_CLOUD_PROXY=http://proxy.example.com:8080
      

Extension Points

  1. Custom Metadata Handling:

    • Extend the adapter to add project-specific metadata:
      class CustomGoogleAdapter extends GoogleCloudStorageAdapter {
          public function put($path, $contents, array $options = []) {
              $options['metadata'] = array_merge(
                  $options['metadata'] ?? [],
                  ['custom_key' => 'custom_value']
              );
              return parent::put($path, $contents, $options);
          }
      }
      
  2. Event Listeners:

    • Listen to file operations via Laravel events:
      Storage::disk('gcs')->put('file.txt', 'content');
      // Trigger custom logic via events (e.g., `filesystem.stored`).
      

3

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport