furaiev / amazon-cognito-identity-dart-2

Unofficial Amazon Cognito Identity Provider Dart SDK, to easily add user sign-up and sign-in to your mobile and web apps with AWS.
MIT License
187 stars 114 forks source link

How to get s3 upload progress #72

Closed SahajRana closed 4 years ago

SahajRana commented 4 years ago

Hi @furaiev, Thanks for this great library & updates on it! I'm wondering if there is a way to get the upload progress through s3 send(). Right now it only returns an empty response after image upload completion.

furaiev commented 4 years ago

Do you get here an empty response?

        final res = await req.send();
        await for (var value in res.stream.transform(utf8.decoder)) {
          print('UploadS3 success $value');
        }

https://gist.github.com/furaiev/e0fff973b31babd36f5c5d7b53d85349

SahajRana commented 4 years ago

I used this approach.

await req.send().then((result) async {
        http.Response.fromStream(result)
            .then((response) {

          print("uploadS3_1> "+utf8.decode(response.bodyBytes).toString());
          return response.body;

        });
      }).catchError((err) => print('error : '+err.toString()))
          .whenComplete(()
      {});

It returns flutter: uploadS3_1> in logs. when the file is completely uploaded. I'm looking for something like: 1%-----40%------80%---100%

furaiev commented 4 years ago

I would recommend you to use dio or some extensions for HTTP like multipart_request

SahajRana commented 4 years ago

Are we not using multipart_request already?

final req = http.MultipartRequest("POST", uri);
    final multipartFile = http.MultipartFile('file', stream, length,
        filename: path.basename(file.path));

    final String fileName = path.basename(file.path);
    final String usrIdentityId = _credentials.userIdentityId;
    final String bucketKey = '${keyResolver.user_email}/$fileName';

    final policy = Policy.fromS3PresignedPost(
        bucketKey,
        'files',
        15,
        _credentials.accessKeyId,
        length,
        _credentials.sessionToken,
        region: backendConstants.aws_region);
    final key = SigV4.calculateSigningKey(
        _credentials.secretAccessKey, policy.datetime, backendConstants.aws_region, 's3');
    final signature = SigV4.calculateSignature(key, policy.encode());

    req.files.add(multipartFile);
    req.fields['key'] = policy.key;
    //req.fields['acl'] = 'public-read'; // Safe to remove this if your bucket has no ACL permissions
    req.fields['X-Amz-Credential'] = policy.credential;
    req.fields['X-Amz-Algorithm'] = 'AWS4-HMAC-SHA256';
    req.fields['X-Amz-Date'] = policy.datetime;
    req.fields['Policy'] = policy.encode();
    req.fields['X-Amz-Signature'] = signature;
    req.fields['x-amz-security-token'] = _credentials.sessionToken;

but

response.progress.listen((int progress) {
      print("progress from response object " + progress.toString());
    });

doesn't work with what we are using already. [as given in multipart_request lib]

SahajRana commented 4 years ago

I looked into multipart_request lib but it is only for android & ios. I'm building a Windows desktop app. Could you help me with dio implementation for s3 upload use-case, dio lib has too many things.

furaiev commented 4 years ago

@SahajRana Please ask to help from dio users community, I don't use it for now.

SahajRana commented 4 years ago

@furaiev, I have resolved it like this. It may be useful for someone. It gives progress like 1%-----40%------80%---100%

    final dio.FormData formData = dio.FormData.fromMap({
      'key':policy.key,
      'X-Amz-Credential': policy.credential,
      'X-Amz-Algorithm': 'AWS4-HMAC-SHA256',
      'X-Amz-Date': policy.datetime,
      'Policy': policy.encode(),
      'X-Amz-Signature': signature,
      'x-amz-security-token': _credentials.sessionToken,
      'file': await dio.MultipartFile.fromFile(
        file.path,
        filename: fileName,
      )
    });

    try {
      await dioObj.postUri(
        uri,
        data: formData,
        onSendProgress: (int sentBytes, int totalBytes) {
          double progressPercent = sentBytes / totalBytes * 100;
          print("$progressPercent %");
          eventBusAwsUpload.fire(BSAwsUploadEvent(fileName,progressPercent));
        },
      );

    } catch (e) {
      print("uploadS3 error> "+e.toString());
    }