首页 > 解决方案 > React-Native, Google Photos API 图片上传

问题描述

反应原生 + 博览会

TL;DR:有没有人有 react-native/expo 使用应用内相机并将图像上传到“新”谷歌 api的工作示例?

  1. 验证用户(工作)
  2. 制作专辑(工作)
  3. 使相册可共享(工作)
  4. 拍照(工作)
  5. 获取 UploadToken(似乎它正在工作)
  6. 上传照片(不工作)

为什么我认为(5)似乎它正在工作,因为 getUploadToken 函数成功返回,响应 200,并提供了一个密钥。

为什么我认为它在 (5) 的另一端可能是一个愚蠢的服务,我可以向它发布几乎任何东西,它会成功返回。

我的预感是我将图像上传到 /uploads 端点的方式有问题。

IE:格式不正确。

this.state.image == {'base64':'base64string','uri':'file://...',...}

我确实看到在我的谷歌照片中创建了一个相册,我可以看到它被设置为可共享,没有权限(用户不能评论,或添加自己的照片)

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 })
    })
  }

标签: react-nativebase64blobgoogle-photosoctetstring

解决方案


5 GET UPLOAD TOKEN API 可以找到,只是 Google 文档上的描述是错误的。输入不是 Base64,而是二进制形式。我在 Postman 中尝试过(截图如下):

获取上传令牌 API: 获取上传令牌 API

上传媒体: 在此处输入图片描述


推荐阅读