Google Drive API:使用 http 请求上传和创建文件夹,例如在 DIO 中使用 Flutter

Google Drive API: Uploading and creating folders with http requests, for example in DIO with Flutter

我正在尝试创建一个与 Google Drive API 交互的简单 Flutter 应用程序。 通过 Google 登录包进行身份验证非常有效,因此我可以访问正确的 headers 和身份验证令牌。

然而我不明白的是,尽管尝试了不同的方法并上下阅读了驱动器文档 - 我如何通过 http 请求与 API 交互,例如通过 Dio 或通过“标准” " dart/flutter?

举一个例子:我想上传一张用户选择的图片。我已经弄清楚了一切(文件路径、授权令牌等),但是 http 请求是什么样子的?

这是“裸”http 请求:

Map headers = await user.currentUser.authHeaders;

var formData = FormData.fromMap({
    'name': filePath,
    'file': MultipartFile.fromBytes(fileData, filename: filePath)
  });

var response = await Dio().post(
      'https://www.googleapis.com/upload/drive/v3/files?uploadType=media',
       data: formData,
      options: Options(headers: headers));

  print(response);

这可能是一个非常mundane/trivial的问题,但我就是想不通..

在此先感谢您的帮助! 克里斯蒂安

您需要先创建文件,然后将文件数据上传到其中。

我将使用 http 插件而不是 DIO。但同样的过程应该适用于 dio。

第一步:在文件夹中创建文件元数据

Future<String> createFile({File image, String folderId}) async {
  String accessToken = await Prefs.getToken();
  Map body = {
    'name': 'name.jpg',
    'description': 'Newly created file',
    'mimeType': 'application/octet-stream',
    'parents': ['$folderId']
  };
  var res = await http.post(
    'https://www.googleapis.com/drive/v3/files',
    headers: {
      'Authorization': 'Bearer $accessToken',
      'Content-Type': 'application/json; charset=UTF-8'
    },
    body: jsonEncode(body),
  );
  if (res.statusCode == 200) {
    // Extract the ID of the file we just created so we 
    // can upload file data into it
    String fileId = jsonDecode(res.body)['id'];
    // Upload the content into the empty file
    await uploadImageToFile(image, fileId);
    // Get file (downloadable) link and use it for anything
    String link = await getFileLink(fileId);
    return link;
  } else {
    Map json = jsonDecode(res.body);
    throw ('${json['error']['message']}');
  }
}

第二步:上传图片数据到空文件

Future uploadImageToFile(File image, String id) async {
  String accessToken = await Prefs.getToken();
  String mimeType = mime(basename(image.path).toLowerCase());
  print(mimeType);
  var res = await http.patch(
    'https://www.googleapis.com/upload/drive/v3/files/$id?uploadType=media',
    body: image.readAsBytesSync(),
    headers: {
      'Authorization': 'Bearer $accessToken',
      'Content-Type': '$mimeType'
    },
  );
  if (res.statusCode == 200) {
    return res.body;
  } else {
    Map json = jsonDecode(res.body);
    throw ('${json['error']['message']}');
  }
}

第三步:获取可下载文件link(存储在数据库中或用于任何用途)

Future getFileLink(String id) async {
  String accessToken = await Prefs.getToken();
  var res = await http.get(
    'https://www.googleapis.com/drive/v3/files/$id?fields=webContentLink',
    headers: {
      'Authorization': 'Bearer $accessToken',
      'Content-Type': 'application/json; charset=UTF-8'
    },
  );
  if (res.statusCode == 200) {
    Map json = jsonDecode(res.body);
    String link = json['webContentLink'];
    return link.split('&')[0];
  } else {
    Map json = jsonDecode(res.body);
    throw ('${json['error']['message']}');
  }
}