7

I am trying to use gapi to upload an image to google cloud storage.The current code I have is

<script src="https://apis.google.com/js/api.js"></script>
<script type="text/javascript">
var imgData = null;

function getImage() {
    navigator.camera.getPicture(onSuccess, onFailure, {
        destinationType: navigator.camera.DestinationType.FILE_URI,
        sourceType: navigator.camera.PictureSourceType.PHOTOLIBRARY
    });

    function onSuccess(imageURI) {
        imgData = encodeImageUri(imageURI);
        var contentLen = imgData.length;
        gapi.load('client', start);
    }

    function onFailure(message) {
        alert("Get image failed: " + message);
    }
}

function start() {
    // 2. Initialize the JavaScript client library.
    console.log('firing google storage api');
    gapi.client.init({
        'apiKey': 'XXX-XX'
    }).then(function() {
        // 3. Initialize and make the API request.
        console.log('api initialized');
        var request = gapi.client.request({
            'path': 'https://www.googleapis.com/upload/storage/v1/b/visionapibucket/o?uploadType=media&name=myObject',
            'method': 'POST',
            'headers': {
                'Content-Type': 'image/jpeg'
            },
            'body': imgData
        });

        try {
            //Execute the insert object request
            console.log('executing call');
            request.execute(function(resp) {
                alert(resp);
            });

        } catch (e) {
            console.log('An error has occurred: ' + e.message);
        }
    }).then(function(response) {
        console.log(response.result);
    }, function(reason) {
        console.log('Error: ' + reason.result.error.message);
    });
};
</script>

I can see that the code is hitting the statement in console is: api initialized

but I don't see the gapi.client.request being called or even printing any error etc.

I am not sure what is wrong here. Please advise

zhm
  • 3,513
  • 3
  • 34
  • 55
Vik
  • 8,721
  • 27
  • 83
  • 168
  • I dont know much about this `google api` but I can tell one thing that the *arguments* for the `gapi.client.request` are `path`,`method`,`params`,`header`,`body` as documented [here](https://developers.google.com/api-client-library/javascript/reference/referencedocs#gapiclientrequestargs),please send your input after you have corrected this. – Pritish Vaidya Jan 10 '17 at 05:05
  • well just path is required all other are optional – Vik Jan 10 '17 at 05:13
  • but `content type` is not a parameter it should be sent as `header {'Content-type' : 'image/jpeg'}`,please send your inputs after correcting this one – Pritish Vaidya Jan 10 '17 at 05:18
  • no didnt help. updated my code in the question – Vik Jan 10 '17 at 05:30
  • one more thing,try using the `gapi.client.request` as a `promise` to *check what `error` it throws and provide its input*.[Helpful link](https://developers.google.com/api-client-library/javascript/features/promises) – Pritish Vaidya Jan 10 '17 at 05:36
  • 1
    Can you move `gapi.client.request` intoto `try`, and see if this statement throws exception. Also, it this site (https://www.googleapis.com/) reachable at your side? – zhm Jan 10 '17 at 05:36
  • no luck on moving to try. it see it still printing the msg "excuting call" and nothing after that in the console logs – Vik Jan 10 '17 at 05:43
  • Following the provided [example](https://developers.google.com/api-client-library/javascript/samples/samples) you should try using the proper [discoveryDocs](https://www.googleapis.com/discovery/v1/apis/storage/v1/rest). You can then directly make the 'gapi.client.storage.objects.insert' request. You can also test out the API first within the [API Explorer](https://developers.google.com/apis-explorer/#search/cloud%20storage/storage/v1/storage.objects.insert) to see an example working request. – Jordan Jan 11 '17 at 21:11

1 Answers1

1

You cannot upload files to Google storage by using just API key. You must have an oauth token.

If the request requires authorization (such as a request for an individual's private data), then the application must provide an OAuth 2.0 token with the request. The application may also provide the API key, but it doesn't have to.

If the request doesn't require authorization (such as a request for public data), then the application must provide either the API key or an OAuth 2.0 token, or both—whatever option is most convenient for you.

https://cloud.google.com/storage/docs/json_api/v1/how-tos/authorizing

In your case, you want to upload so you must have an oauth token.

You have several workaround:

  • You can upload the file to your server, and upload it using you server credentials by using service account.
    https://cloud.google.com/compute/docs/access/service-accounts

  • You can create a token on your server, and send it to your client. Then the client can upload one file to your Google Storage account without a permanent access token

  • You can upload to the Google Storage account of your users. For do so, they must login to your app. https://developers.google.com/identity/protocols/OAuth2

  • The last method is, you can upload the files to your server, and copy it to the cloud by executing gutil mv command. In this case all you have to do is to login once to your Google cloud account by using gcloud auth gustil mv, gcloud mv command

More info about gcloud utility, and to download it: https://cloud.google.com/sdk/

Community
  • 1
  • 1
Aminadav Glickshtein
  • 23,232
  • 12
  • 77
  • 117
  • i agree what you said above but my question here is that even the call does not happen. i should see a auth error or permission error. isnt it? – Vik Jan 12 '17 at 20:18
  • @Aminadav, Can I get the hit for `You can create a token on your server, and send it to your client. Then the client can upload one file to your Google Storage account without a permanent access token` that you mentioned? – sungyong May 09 '19 at 11:35