Search code examples
firebaseaxiosgoogle-cloud-functionsbearer-tokengoogle-cloud-vision

Authorization Bearer Token for Cloud Vision API


Problem

I've written a cloud function that takes a base64 string and passes it into the Google Cloud Vision API, and I've also written a function on the client that calls a Firebase Cloud Function via HTTP.

Although the data passes along well from the client to the Cloud Function, the request to the Google Vision API from the server doesn't work. I get a status code 500 error.

I'm pretty sure this has to do with the Authorization bearer token, because running this in the shell with the environment variable GOOGLE_APPLICATION_CREDENTIALS works just fine. By the way, the same environment variable is present when running the Cloud Function.

curl -X POST \
-H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
https://vision.googleapis.com/v1/images:annotate

Am I using the correct bearer token (see code below)? How would I be able to get this request to go through?

Client Side

auth.currentUser.getIdToken()
        .then((idToken) => {
          axios({
            method: 'post',
            url: 'http://localhost:5001/project/my-endpoint',
            data: qs.stringify({
              imageData: image,
              token: idToken
            }),
            maxContentLength: 100000,
            maxBodyLength: 100000
          }) // .then, .catch follows...
        })

Server Side

axios({
        method: 'post',
        url: 'https://vision.googleapis.com/v1/images:annotate',
        headers: {
            "Authorization": `Bearer ${request.body.token}`,
            "Content-Type": "application/json; charset=utf-8"
        },
        data: {
            "requests": [
                {
                    "image": {
                        "content": request.body.imageData   
                    },
                    "features": [
                        {
                            "type": "DOCUMENT_TEXT_DETECTION"
                        }
                    ]
                }
            ]
        },
        maxContentLength: 100000,
        maxBodyLength: 100000
    }) // .then, .catch follows...

Solution

  • The best solution is to use the client library. The docs on Google's page aren't so great, but these docs are much better.

    The code should look something like this:

    const vision = require('@google-cloud/vision')
    const client = new vision.ImageAnnotatorClient()
    
    const fileName = request.body.imageData // base64 image data
    
        const req = {
            image: {
                content: fileName
            }
        }
    
        client.documentTextDetection(req)
            .then(result => response.send(result))
            .catch(error => response.send(error))
    })