supabase / supabase-flutter

Flutter integration for Supabase. This package makes it simple for developers to build secure and scalable products.
https://supabase.com/
MIT License
698 stars 163 forks source link

Integrate TUS client #438

Open Vinzent03 opened 1 year ago

Vinzent03 commented 1 year ago

Is your feature request related to a problem? Please describe. As proposed here it seems like it's not planned to integrate the tus client into supabase-js, because there is already the great library uppy.js. Though the best TUS client for Dart I found was this one, which doesn't support Web for persistent storage and is a fork from an older package.

Describe the solution you'd like I think it feels more in Supabase integrated if the existing supabase-dart client would support TUS as well. So my proposal would be to integrate it in storage-dart.

dshukertjr commented 1 year ago

There actually is a plan to integrate tus client on js library. We can wait to see how that plays out, and bring it over to the Flutter library!

prafulfillment commented 1 year ago

What's the status on this for Flutter?

dshukertjr commented 1 year ago

@prafulfillment We are still evaluating the optimal developer experience for the client side implementation of resumable uploads across all client libraries.

theShreyans commented 1 year ago

Correct me if I'm wrong. After the launch week, it seems like resumable uploads are still not available for all projects and are made available per project basis. In that case is there any workaround as of now for flutter-related projects? I'm working on a project that lets the user upload max 100 MB of files but without upload progress or cancelling uploads or resuming them, it would be impossible. Also, I tried integrating a custom Backblaze storage option but was too much work.

dshukertjr commented 1 year ago

@theShreyans You can contact Supabase support if you want resumable uploads turned on for your Supabase project.

Implementing TUS protocol on the client library is in progress. We ask to patiently wait for it to be complete. In the mean while, you may explorer third party TUS client libraries such as this one https://pub.dev/packages/tus_client_dart

rlee1990 commented 1 year ago

@dshukertjr any updates on this for flutter?

rlee1990 commented 7 months ago

Any updates on this?

dshukertjr commented 7 months ago

@rlee1990 Will add this to supabase-flutter once they add it to the js client. https://github.com/supabase/storage-js/pull/189

JEndler commented 6 months ago

I'd also be interested in this.

In the meantime, I've been trying to get the resumable upload to work with https://pub.dev/packages/tus_client_dart, here's a version that works for me :) Might save someone some time:

// Function to pick a file
Future<XFile> pickFile(List<String> allowedExtensions) async {
  // Function to pick files
  FilePickerResult? result = await FilePicker.platform.pickFiles(
    type: FileType.custom,
    allowedExtensions: allowedExtensions
  );
  if (result != null) {
    XFile file = XFile(result.files.single.path!);
    return file;
  } else {
    // User canceled the picker
    return XFile('');
  }
}

// Function to pick files and upload to Supabase Storage using TUS
Future<void> pickFilesAndUploadToSupabaseWithTUS() async {
  try {
    // Function to pick files, only allows zip files
    XFile? file = await pickFile(['zip']);

    String uid = Supabase.instance.client.auth.currentUser!.id;

    // Create a new TusClient instance
    final tusClient = TusClient(file, store: TusMemoryStore());

    // function to print progress
    void printOnProgress(double progress, Duration duration) {
      print('Progress: $progress% and $duration time');
    }

    // Starts the upload
    await tusClient.upload(
      uri: Uri.parse(
        // This resolves to our Supabase Storage URL
          '${dotenv.env['SUPABASE_URL']!}/storage/v1/upload/resumable'),
      headers: {
        'Authorization': 'Bearer ${Supabase.instance.client.auth.currentSession?.accessToken}',
        // Set to true to enable overwrite
        'x-upsert': 'true'
      },
      metadata: {
        'bucketName': 'bucketname',
        'objectName': '$uid/${file.path.split('/').last}',
        'contentType': 'application/zip',
      },
      onStart: (TusClient client, Duration? estimate) {
        // If estimate is not null, it will provide the estimate time for completion
        // it will only be not null if measuring upload speed
        print('This is the client to be used $client and $estimate time');
      },
      onComplete: () {
        print("Complete!");
        // Prints the uploaded file URL
        print(tusClient.uploadUrl.toString());
      },
      onProgress: printOnProgress,
      // Set this to true if you want to measure upload speed at the start of the upload
      measureUploadSpeed: true,
    );
   }
iampopal commented 3 months ago

I'd also be interested in this.

In the meantime, I've been trying to get the resumable upload to work with https://pub.dev/packages/tus_client_dart, here's a version that works for me :) Might save someone some time:

// Function to pick a file
Future<XFile> pickFile(List<String> allowedExtensions) async {
  // Function to pick files
  FilePickerResult? result = await FilePicker.platform.pickFiles(
    type: FileType.custom,
    allowedExtensions: allowedExtensions
  );
  if (result != null) {
    XFile file = XFile(result.files.single.path!);
    return file;
  } else {
    // User canceled the picker
    return XFile('');
  }
}

// Function to pick files and upload to Supabase Storage using TUS
Future<void> pickFilesAndUploadToSupabaseWithTUS() async {
  try {
    // Function to pick files, only allows zip files
    XFile? file = await pickFile(['zip']);

    String uid = Supabase.instance.client.auth.currentUser!.id;

    // Create a new TusClient instance
    final tusClient = TusClient(file, store: TusMemoryStore());

    // function to print progress
    void printOnProgress(double progress, Duration duration) {
      print('Progress: $progress% and $duration time');
    }

    // Starts the upload
    await tusClient.upload(
      uri: Uri.parse(
        // This resolves to our Supabase Storage URL
          '${dotenv.env['SUPABASE_URL']!}/storage/v1/upload/resumable'),
      headers: {
        'Authorization': 'Bearer ${Supabase.instance.client.auth.currentSession?.accessToken}',
        // Set to true to enable overwrite
        'x-upsert': 'true'
      },
      metadata: {
        'bucketName': 'bucketname',
        'objectName': '$uid/${file.path.split('/').last}',
        'contentType': 'application/zip',
      },
      onStart: (TusClient client, Duration? estimate) {
        // If estimate is not null, it will provide the estimate time for completion
        // it will only be not null if measuring upload speed
        print('This is the client to be used $client and $estimate time');
      },
      onComplete: () {
        print("Complete!");
        // Prints the uploaded file URL
        print(tusClient.uploadUrl.toString());
      },
      onProgress: printOnProgress,
      // Set this to true if you want to measure upload speed at the start of the upload
      measureUploadSpeed: true,
    );
   }

Does this example works to check progress of uploading?

iampopal commented 3 months ago

I am looking and need to check progress of uploading files, when this could be included?

iampopal commented 3 months ago

@dshukertjr When will Uploading progress be added in flutter storage?

iampopal commented 3 months ago

As resumable uploads are added in JS Library, will be great to add steps for adding it to flutter too.

https://supabase.com/docs/guides/storage/uploads/resumable-uploads?queryGroups=language&language=js

dshukertjr commented 3 months ago

@iampopal I Love the enthusiasm, but I would appreciate it if you could refrain from spamming the same issue with four consecutive comments. supabase_flutter will add resumable upload support when JS SDK gets the resumable upload feature. You can check this PR to monitor it. In the meantime, you can implement resumable uploads using a third-party library like this lovely example.

itsatifsiddiqui commented 1 month ago

Hi everyone,

I encountered the need to upload files and track their progress while using the Supabase Flutter SDK and realized others might be facing the same issue. To address this, I’ve developed and published a package: supabase_progress_uploads.

This package supports uploading files with real-time progress updates and can handle multiple file uploads simultaneously. It’s based on a code snippet provided by @JEndler, to whom I’m very grateful.

Feel free to check it out and see if it fits your needs!