781flyingdutchman / background_downloader

Flutter plugin for file downloads and uploads
Other
162 stars 76 forks source link

Cannot enqueue download task for AWS pre-signed URL object #218

Closed hsoniwork closed 9 months ago

hsoniwork commented 10 months ago

Describe the bug I have implemented this plugin and it works well in Android whereas on iOS I cannot see if the task has been enqueued so far or not. I have followed all the instructions and have enabled the background fetch for the project too. I am also requesting all the image permissions to save in the library.

To Reproduce Since there is no similar bug here on GitHub then my steps may not be applicable as it is too generic. I am just setting the up plugin as per the instructions. I am not sure what will be needed to resolve this issue.

Expected behavior The expected behavior is enqueue() method should return true or false if I am awaiting the call e.g. await FileDownlaoder().enqueue()

Logs

I see Starting task <task_id> and
Some timeout information

Code

//Method to generate S3 bucket URL from amplify storage. I have checked all the permissions for object access. 
Future<Map<String, dynamic>> getDownloadableUrl(
    String fileName,
  ) async {
    try {
      final result = await amplify.Amplify.Storage
          .getUrl(
            key: fileName,
            options: const amplify.StorageGetUrlOptions(
              accessLevel: amplify.StorageAccessLevel.guest,
              pluginOptions: S3GetUrlPluginOptions(
                validateObjectExistence: true,
                expiresIn: Duration(days: 1),
              ),
            ),
          )
          .result;
      Uri fileUri = Uri.parse(result.url.toString());
      Map<String, String> queryParams = {};
      fileUri.queryParameters.forEach((key, value) {
        queryParams.addEntries({key: Uri.encodeQueryComponent(value)}.entries);
      });
      return {
        'url': result.url.toString(),
        'queryParams': queryParams,
      };
    } on amplify.StorageException catch (e) {
      amplify.safePrint('Could not get a downloadable URL: ${e.message}');
      rethrow;
    }
  }
// Creating download task based on the URL and query params received from above method
final task = DownloadTask(
              taskId: fishDownloadTaskId,
              url: map['url'],
              group: "sampleGroup,
              filename:
                  "temp_file_name",
              urlQueryParameters: map['queryParams'],
              retries: 5,
              displayName: "Downloading data,
              allowPause: true,
              metaData: 'Sample test data');
var isSuccess = await FileDownloader().enqueue(task);
print(isSuccess); //prints nothing at all. Just seeing the Starting task <task_id> on log

Snapshot from Xcode

Screenshot 2023-12-19 at 10 52 41 PM
781flyingdutchman commented 10 months ago

Hi, thanks for raising the issue. It's a bit hard to follow as I am not familiar with S3. Can you please check out tissue #181 and see if that help solve your problem?

hsoniwork commented 10 months ago

Hi @781flyingdutchman,

Thank you for your response. Unfortunately, it didn't work for me. I checked the issue before logging the new one. Also, just for your information, when I say pre-signed URL, basically its the URL to an object/file on File storage on AWS. Same URL is working well for the Android app. So for the iOS I am not sure what really is causing the issue?

My logical guess says that:

Let me know what do you think of these?

781flyingdutchman commented 10 months ago

Thanks, and yes if it works as intended on Android and that same code/url does not run on iOS then that is indeed strange.

In response to your questions:

I have one additional question is there any indication that the task actually starts or completes? This should be visible in the Console logs in the form of many messages related to urlsession.

Let's see if the logs and these experiments offer some insight.

hsoniwork commented 10 months ago

Thank you for the response. Allow me tomorrow's time and I will share the required details with you soon.

hsoniwork commented 10 months ago

Hi @781flyingdutchman Here are the logs for [Downlaoder] in debug mode from Android Studio.

[Downloader] Starting task with id <our_unique_object_id_aws>
[Downloader] timeoutIntervalForResource = 14400 seconds
[Downloader] timeoutIntervalForRequest = 60 seconds
[Downloader] Not using proxy for any task

For URL, yes it is encoded properly and that is why it is working fine on Android without an issue.

Here is the flutter doctor summary for your reference

Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.13.9, on macOS 14.0 23A344 darwin-x64, locale en-IN)
[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 15.0.1)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2022.3)
[✓] VS Code (version 1.85.1)
[✓] Connected device (4 available)
[✓] Network resources

I have already tried the simple URL with one of the tasks previously. It has the same issue.

Yes, as per logs, I am seeing that task is Starting but no messages for completion.

Here is the code that I have written for a task enqueue.

 try {
    var isEnqueued = await FileDownloader().enqueue(value);
     print("Enqueue $isEnqueued");
   } catch (e) {
     print(e);
   }

It is not even printing the later statement whether it got enqueued or not.

P.S.: The above logs that I have shared comes up when I schedule a task for the first time but when I try to trigger another task I see only the first line "Starting task ..." and no other logs. Not sure why.

Please let me know if any more information is needed or not.

Thank you.

781flyingdutchman commented 10 months ago

If it's not working for a simple URL either then I really do think it's an issue with your setup somehow. Can you 'untick' the 'Background processing' capability (it's not needed for the downloader) and compare your Info.plist with the one in the plugin example app to make sure you haven't missed anything?

hsoniwork commented 10 months ago

I did what you have suggested. The difference that I see in info.plist is fetch string is removed from it.

<string>fetch</string>

hsoniwork commented 10 months ago

@781flyingdutchman Any idea when would I get this error on my logs?

[Downloader] Failed to move file from /private/var/mobile/Containers/Data/Application/568E2C78-1A85/Library/Caches/com.apple.nsurlsessiond/Downloads/com.etournament.fishing.testflight/CFNetworkDownload_p83cJc.tmp to /var/mobile/Containers/Data/Application/568E2C78-1A85/Documents/file_name3.37_25 Dec, 2023.jpg: “CFNetworkDownload_p83cJc.tmp” couldn’t be moved to “Documents” because either the former doesn’t exist, or the folder containing the latter doesn’t exist.

781flyingdutchman commented 10 months ago

I did what you have suggested. The difference that I see in info.plist is fetch string is removed from it.

<string>fetch</string>

So, does it work after you made this change?

@781flyingdutchman Any idea when would I get this error on my logs?

It would be helpful to add the code that triggered this error. Based on the log, it appears you called moveToSharedStorage but the path you're moving it to doesn't seem to fit any SharedStorage destinations.

hsoniwork commented 10 months ago

No, it did not work after the code change. I occasionally see this log when I run the app for the first time and also trigger the first download. So not sure what is wrong with it.

I have tried the example you have shared on GitHub for this plugin. Following things I tried.

//base_downloader.dart, Line number 282 
final enqueueSuccess = await enqueue(taskToEnqueue);

What could be the reasons of the enqueue() method not returning at all?

781flyingdutchman commented 10 months ago
  • When I tried copying the same method processLoadAndOpen in my code base and triggered the download then it didn't go through this line from _basedownloader.dart file. I did not get any response back from enqueue() method.

If you're trying to download the same file as in the sample app, then this really does suggest an issue with your setup/configuration. Have you looked at the Console? On a Mac, this is where the detailed logs of the attached simulator or device show up - Android studio only shows a subset. Perhaps there is some guidance in there as to why this error occurs.

hsoniwork commented 10 months ago

Yes, I tried running the app from Xcode and checked the console. But no other logs are coming up.

jamescardona11 commented 10 months ago

I'm not sure if this is a library problem because I currently have my system to download and upload files to s3 with pre-signed url and everything works for me.

github-actions[bot] commented 9 months ago

This issue is stale because it has been open for 14 days with no activity.

github-actions[bot] commented 9 months ago

This issue was closed because it has been inactive for 7 days since being marked as stale.