React-Native, Google Фото API Загрузка изображений

реакция-родной + экспо

TL;DR: есть ли у кого-нибудь рабочий пример реакции-натива / экспо, работающего с камерой в приложении и загружающего изображение в "новый" API Google?

  1. Аутентифицировать пользователя (работает)
  2. Сделать альбом (рабочий)
  3. Сделать альбом общедоступным (рабочий)
  4. Сфотографируй (работает)
  5. Get UploadToken (похоже, это работает)
  6. Загрузить фото (не работает)

Почему (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')

Другие вопросы по тегам