2

反应原生 + 博览会

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

3 回答 3

3

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

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

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

于 2019-02-01T09:23:10.170 回答
1

我一直在 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')

于 2018-12-18T09:58:24.517 回答
1

第 5 步当然行不通……您根本没有发送图像!

在第 4 步中,您将其称为:

this.getUploadToken()

在第 5 步时

getUploadToken = (image) => {

然后将图像用作主体。

您在测试时检查过您的网络选项卡吗?看起来您会收到 400 错误。

于 2018-12-22T13:13:39.590 回答