React-Native, Google Фото API Загрузка изображений
реакция-родной + экспо
TL;DR: есть ли у кого-нибудь рабочий пример реакции-натива / экспо, работающего с камерой в приложении и загружающего изображение в "новый" API Google?
- Аутентифицировать пользователя (работает)
- Сделать альбом (рабочий)
- Сделать альбом общедоступным (рабочий)
- Сфотографируй (работает)
- Get UploadToken (похоже, это работает)
- Загрузить фото (не работает)
Почему (5) кажется, что это работает, потому что функция getUploadToken успешно возвращает ответ 200 и предоставляет ключ.
Почему я думаю, что это может быть глупый сервис на другом конце (5), я могу опубликовать практически что угодно, и он вернется успешно.
Я догадываюсь, что с загрузкой изображения в конечную точку /uploads что-то не так.
IE: не в правильном формате.
this.state.image == {'base64': 'base64string', 'uri': 'file: //...',...}
Я вижу, что в моих фотографиях Google создается альбом, и я вижу, что он настроен для общего доступа без каких-либо привилегий (пользователи не могут комментировать или добавлять свои собственные фотографии)
2 СДЕЛАТЬ АЛЬБОМ
makeAlbum = () => {
//MAKE ALBUM
fetch('https://photoslibrary.googleapis.com/v1/albums', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer '+this.state.accessToken
},
body: JSON.stringify({
"album": {"title": this.state.albumTemp}
}),
}).then((response) => response.json())
.then((response) => {
[
this.shareAlbum(response),
console.log('make: ',response)
]
});
}
}
3 СДЕЛАТЬ АЛЬБОМ ПОДЕЛИТЬСЯ
shareAlbum = (response) =>{
this.setState({albumId:response.id})
//MAKE ALBUM SHAREABLE
fetch('https://photoslibrary.googleapis.com/v1/albums/'+this.state.albumId+':share',{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer '+this.state.accessToken
}
}).then((response) => response.json())
.then((response)=>{
[
this.setState({shareable:response.shareInfo.shareableUrl}),
console.log('share1: ',this.state.shareable),
console.log('share2: ',response),
]
});
}
4 ФОТО СЪЕМКИ
capturePhoto = async () => {
let image = await this._camera.takePictureAsync({
base64: true,
quality: .5,
width: 1920,
fixOrientation: true
})
this.setState({ image: image, capturing: false })
// delay the capture a few seconds to make sure it's rendered
setTimeout(async () => {
let result = await takeSnapshotAsync(this._previewRef, {
format: 'png',
result: 'tmpfile',
quality: 1
});
//upload the photo to google photos album
this.getUploadToken(image)
}, 1000)
}
5 ПОЛУЧИТЬ ТОКЕН
getUploadToken = (image) => {
let name = this.state.image.uri.split('/')
name=name[name.length-1]
fetch('https://photoslibrary.googleapis.com/v1/uploads', {
method: 'POST',
headers: {
'Content-Type': 'application/octet-stream',
'Authorization': 'Bearer '+this.state.accessToken,
'X-Goog-Upload-File-Name': name,
'X-Goog-Upload-Protocol': 'raw'
},
body:image,
})
.then((response) => {
console.log('setup upload: ',response)
this.uploadPhoto(response._bodyText);
})
}
6 ЗАГРУЗИТЬ ФОТО
uploadPhoto = (token) => {
fetch('https://photoslibrary.googleapis.com/v1/mediaItems:batchCreate', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer '+this.state.accessToken,
},
body:JSON.stringify({
"albumId": this.state.albumId,
"newMediaItems": [
{
"description": "Event Photo",
"simpleMediaItem": {
"uploadToken": token
}
}
]
})
})
.then((response) => {
console.log('actual upload: ',response)
this.setState({ ready: true, image: null })
})
}
3 ответа
5 ПОЛУЧИТЕ ЗАГРУЗИТЬ ТОКЕН API работает найти, просто описание неправильно в документации Google. Вместо Base64 вход имеет двоичную форму. Я пытался в Почтальон (ниже скриншот):
Получить API загрузки токена: Получить API загрузки токена
Загрузить медиа: введите описание изображения здесь
Шаг 5 конечно не работает... Вы не отправляете изображение вообще!
На шаге 4 вы называете это:
this.getUploadToken()
Пока на шаге 5
getUploadToken = (image) => {
изображение затем используется в качестве тела.
Вы проверяли свою вкладку сети во время тестирования? Похоже, вы получите 400 ошибок.
Я пытался сделать то же самое в приложении Node Express.
Не забывайте, что вам нужно загружать изображение в двоичном формате, а не в base64.
Также похоже, что вы не передаете параметр на шаге 4 в функцию getUploadToken().
Мое приложение также возвращает "message": "NOT_IMAGE: There was an error while trying to create this media item."
,
В моем приложении узла я преобразовываю буфер в двоичный файл с
const fileBinary = file.data.toString('binary')