API Google Диска: Загрузка и создание папок с http-запросами, например, в DIO с помощью Flutter

#flutter #dart #google-api #google-drive-api #dio

Вопрос:

Я пытаюсь создать простое приложение Flutter, которое взаимодействует с API Google Диска. Аутентификация отлично работает с помощью пакета входа в Google, поэтому у меня есть доступ к правильным заголовкам и токенам аутентификации.

Однако чего я не понимаю, несмотря на то, что я пробовал разные подходы и читал документацию по приводу вверх и вниз — как я могу взаимодействовать с API через http-запросы, например, через 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);
 

Вероятно, это очень приземленный/тривиальный вопрос, но я просто не могу его понять ..

Заранее спасибо за вашу помощь! Христианин

Ответ №1:

Сначала вам нужно создать файл, а затем загрузить в него данные файла.

Я буду использовать 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']}');
  }
}
 

Шаг третий: Получите ссылку на загружаемый файл(для хранения в базе данных или использования для чего-либо)

 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('amp;')[0];
  } else {
    Map json = jsonDecode(res.body);
    throw ('${json['error']['message']}');
  }
}
 

Комментарии:

1. Большое вам спасибо! Эти три шага действительно помогают мне понять синтаксис http-запросов в сочетании с API Google Диска. Мне не удалось «перевести» документацию по API диска на реальные запросы, поэтому теперь я могу учиться на ваших шагах и примерах. Еще раз спасибо вам!