Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

how to upload an image(s) to Google Cloud #167

Closed
fritz-playmaker opened this issue Feb 11, 2019 · 3 comments
Closed

how to upload an image(s) to Google Cloud #167

fritz-playmaker opened this issue Feb 11, 2019 · 3 comments

Comments

@fritz-playmaker
Copy link

fritz-playmaker commented Feb 11, 2019

Hi, I am trying to upload an image of jpeg file format to Google Cloud but I keep on getting one of my metatdata responses as contentType: multipart/form-data; boundary=--dioBoundary&Happycoding-3148554670 instead of "contentType": "image/jpeg",, thus corrupting the file in the cloud

This is my source reference

I have seen your example in , but i wish there could be on uploading to Google Cloud.

Steps to Reproduce

 dioUpload(String imagePath) async {
  var dio = new Dio();

List splitFormat = imagePath.split("captured_images/"); //split path to get image name

FormData pictureData = new FormData.from({
  "name":"media/image/${splitFormat[1]}",
  "file": new UploadFileInfo(new File(imagePath), "${splitFormat[1]}"),
});

Response response = await dio.post(
  "https://www.googleapis.com/upload/storage/v1/b/test/o?uploadType=multipart&key=xxx",
  data: pictureData,
  options: new Options(contentType: ContentType.parse("multipart/related")),
);
   }

Logs

 E/flutter (11566): [ERROR:flutter/shell/common/shell.cc(184)] Dart Error: Unhandled exception:
 E/flutter (11566): DioError [DioErrorType.RESPONSE]: Http status error [400]
 E/flutter (11566): #0      Dio._request (package:dio/src/dio.dart:604:12)
 E/flutter (11566): <asynchronous suspension>
 E/flutter (11566): #1      Dio.request (package:dio/src/dio.dart:518:12)
 E/flutter (11566): <asynchronous suspension>
 E/flutter (11566): #2      Dio.post (package:dio/src/dio.dart:107:12)
 E/flutter (11566): #3      SubmitData.dioUpload (package:opine_app/utils/submission.dart:184:35)
 E/flutter (11566): <asynchronous suspension>
 E/flutter (11566): #4      SubmitData.submitCapturedData (package:opine_app/utils/submission.dart:125:11)
 E/flutter (11566): #5      _RootZone.runUnary (dart:async/zone.dart:1379:54)
 E/flutter (11566): #6      _FutureListener.handleValue (dart:async/future_impl.dart:129:18)
 E/flutter (11566): #7      Future._propagateToListeners.handleValueCallback      
 (dart:async/future_impl.dart:642:45)
 E/flutter (11566): #8      Future._propagateToListeners (dart:async/future_impl.dart:671:32)
 E/flutter (11566): #9      Future._complete (dart:async/future_impl.dart:476:7)
 E/flutter (11566): #10     _SyncCompleter.complete (dart:async/future_impl.dart:51:12)
 E/flutter (11566): #11     _AsyncAwaitCompleter.complete           
 (dart:async/runtime/libasync_patch.dart:28:18)
 E/flutter (11566): #12     _completeOnAsyncReturn (dart:async/runtime/libasync_patch.dart:295:13)
 E/flutter (11566): #13     _withClient (package:http/http.dart)
 E/flutter (11566): #14     _RootZone.runUnary (dart:async/zone.dart:1379:54)
 E/flutter (11566): #15     _FutureListener.handleValue (dart:async/future_impl.dart:129:18)
 E/flutter (11566): #16     Future._propagateToListeners.handleValueCallback                
 (dart:async/future_impl.dart:642:45)
 E/flutter (11566): #17     Future._propagateToListeners (dart:async/future_impl.dart:671:32)
 E/flutter (11566): #18     Future._completeWithValue (dart:async/future_impl.dart:486:5)
 E/flutter (11566): #19     Future._asyncComplete.<anonymous closure> 
 (dart:async/future_impl.dart:516:7)
 E/flutter (11566): #20     _microtaskLoop (dart:async/schedule_microtask.dart:41:21)
 E/flutter (11566): #21     _startMicrotaskLoop (dart:async/schedule_microtask.dart:50:5)
@fritz-playmaker fritz-playmaker changed the title Upload image to Google Cloud how to upload an image(s) to Google Cloud Feb 11, 2019
@wendux
Copy link
Contributor

wendux commented Feb 21, 2019

If you use FormData, the request contentType will be set to "multipart/form-data" (ignoring options.contentType), there are two ways to upload file to Google cloud.

  1. Performing a Simple Upload; Please refer to https://cloud.google.com/storage/docs/json_api/v1/how-tos/simple-upload, a simple example as follows( dio version 2.0.12):
  var imgFile=new File("");
  String savePath="";
  String token="xxx";

  // Sending stream
  await dio.post(
    "https://www.googleapis.com/upload/storage/v1/b/opine-world/o?uploadType=media&name=$savePath",
    data: imgFile.openRead(), // Post with Stream<List<int>>
    options: Options(
      headers: {
        HttpHeaders.contentTypeHeader: ContentType.text,
        HttpHeaders.contentLengthHeader: imgFile.lengthSync(),
        // Set content-length
        HttpHeaders
            .authorizationHeader: "Bearer $token"
      },
    ),
  );
  1. Format the body according to the multipart/related content type RFC 2387 by hand.

@wendux wendux closed this as completed Feb 25, 2019
@wendux wendux reopened this Feb 28, 2019
@wendux wendux closed this as completed Mar 6, 2019
@ollyde
Copy link

ollyde commented Apr 9, 2022

For anyone who wants to support cross platform (Web/Desktop & Mobile) here is an alternative; since Web files don't always have path included and only name.

 MultipartFile fileUpload;
      if (file.path != null) {
        fileUpload = await MultipartFile.fromFile(file.path!, filename: file.name);
      } else {
        fileUpload = MultipartFile.fromBytes(file.bytes as List<int>, filename: file.name);
      }

      final dio = Dio();
      await dio.put(
        fileUploadUrl.uploadUrl,
        data: fileUpload.finalize(),
        // data: File(file.path!).readAsBytesSync(),
        // data: FormData.fromMap({"file": fileUploadData}),
        options: Options(headers: {
          'Accept': "*/*",
          HttpHeaders.contentLengthHeader: fileUpload.length.toString(),
          'Connection': 'keep-alive',
        }),
        onSendProgress: (bytes, total) {
          uploadProgresses[localIndex] = bytes / total;
          final average = uploadProgresses.map((m) => m).reduce((a, b) => a + b) / uploadProgresses.length;
          if (kDebugMode) {
            // print("bytes: " + bytes.toString());
            // print("total: " + total.toString());
            // print("average: " + average.toString());
          }
          onUploadProgress(average);
        },
      );

@dancb10
Copy link

dancb10 commented Jan 31, 2024

@ollyde but will the fileUpload = await MultipartFile.fromFile(file.path!, filename: file.name); load the whole file in memory?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants