React-Native,Google 照片 API 图片上传

React-Native, Google Photos API Image Upload

react-native + expo

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

  1. 验证用户(工作)
  2. Make Album(工作)
  3. Make Album Shareable(工作中)
  4. 拍照(工作)
  5. Get UploadToken(好像有效)
  6. Upload Photo(不工作)

为什么我认为 (5) 似乎有效,因为 getUploadToken 函数 return 成功,响应 200,并提供了一个密钥。

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

我的预感是我将图像上传到 /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 })
    })
  }

我一直在 Node Express 应用程序中尝试同样的事情。
不要忘记您需要以二进制格式而不是 base64 格式上传图像。
看起来您没有在第 4 步中将参数传递给函数 getUploadToken()。

我的应用程序还 returns "message": "NOT_IMAGE: There was an error while trying to create this media item."

在我的节点应用程序中,我使用

将缓冲区转换为二进制文件

const fileBinary = file.data.toString('binary')

第 5 步肯定行不通...您根本没有发送图像!

在第 4 步中,您称之为:

this.getUploadToken()

在第 5 步中

getUploadToken = (image) => {

图像然后用作正文。

您在测试时是否检查了您的网络选项卡?您似乎会收到 400 错误。

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

获取上传令牌API: Get Upload Token API

上传媒体: enter image description here