#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 диска на реальные запросы, поэтому теперь я могу учиться на ваших шагах и примерах. Еще раз спасибо вам!