atali
atali

Reputation: 53

Android with Google Cloud Storage got Invalid Credentials

I want to use Google Storage from my android device. I enable google storage service and google storage json api. I enable the billing too.

I got my SHA1 fingerprint from the following command line :

keytool -list -v -keystore  ~/.android/debug.keystore 

I set the "SHA1 key;com.mydomain" in the api console and I got my Simple API.

I am trying to get the content of the bucket but I am stuck with the following error:

 com.google.api.client.googleapis.json.GoogleJsonResponseException: 401 Unauthorized
    {
    "code" : 401,
    "errors" : [ {
    "domain" : "global",
    "location" : "Authorization",
    "locationType" : "header",
    "message" : "Invalid Credentials",
    "reason" : "authError"
    } ],
    "message" : "Invalid Credentials"
    }
    at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:111)
    at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:38)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest$1.interceptResponse(AbstractGoogleClientRequest.java:312)
    at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1042)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:410)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:343)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:460)
    at com.zenittude.image.importer.GoogleCloudStorageImageImporter.getBucket(GoogleCloudStorageImageImporter.java:183)
    at com.zenittude.image.importer.GoogleCloudStorageImageImporter.access$300(GoogleCloudStorageImageImporter.java:61)
    at com.zenittude.image.importer.GoogleCloudStorageImageImporter$BucketTask.doInBackground(GoogleCloudStorageImageImporter.java:212)
    at com.zenittude.image.importer.GoogleCloudStorageImageImporter$BucketTask.doInBackground(GoogleCloudStorageImageImporter.java:194)
    at android.os.AsyncTask$2.call(AsyncTask.java:287)
    at java.util.concurrent.FutureTask.run(FutureTask.java:234)
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
    at java.lang.Thread.run(Thread.java:856)

This is my class :

    @EBean
public class GoogleCloudStorageImageImporter implements IImageImporter {

    public static final String TAG = "GoogleCloudStorageImageImporter";

    private static final String APPLICATION_NAME = "MyCompany-MyApp/1.0";

    private final JsonFactory JSON_FACTORY = new JacksonFactory();

    private HttpTransport transport = AndroidHttp.newCompatibleTransport();


    private GoogleCloudSettings settings;


    private Storage storage;

    @RootContext
    Activity activity;

    @RootContext
    Context context;


    @Bean(DefaultImageManager.class)
    IImageManager imageManager;

    @Bean(OrmliteRepositoryManager.class)
    ILocalRepository repository;

    Account account;

    GoogleAccountCredential credential;




    private void readSettings() {
        settings = GoogleCloudSettings.load(JSON_FACTORY,
                                            GoogleCloudSettings.class.getResourceAsStream("/foo_settings.json"));

        settings.setBucket("client-" + MainApplication.getBusinessId());

    }

    private Storage getStorageService() {

        StorageRequestInitializer storageRequestInitializer = new StorageRequestInitializer(ClientCredentials.API_KEY);

        return new Storage.Builder(transport,
                                    JSON_FACTORY,
                                    credential)
                                    .setApplicationName(APPLICATION_NAME)
                                    .setStorageRequestInitializer(storageRequestInitializer)
                                    .build();
    }


    public void doImport() {

        try {
            // settings
            readSettings();

            if( account == null) {
                GoogleAccountManager googleAccountManager = new GoogleAccountManager(activity);
                Account[] accounts = googleAccountManager.getAccountManager().getAccountsByType(GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE);
                account = accounts[2];
            }


            new BucketTask().execute(account);

        } catch (Throwable t) {
            Log.e(TAG, "Error while trying to import images from server",  t);
        }
    }

    private Bucket getBucket() {

        Log.i("Getting bucket " + settings.getBucket() + " metadata");
        Bucket bucket = null;
        try {
            Storage.Buckets.Get getBucket = storage.buckets().get(settings.getBucket());
            getBucket.setPrettyPrint(true);
            bucket = getBucket.execute();
            Log.i(bucket.toPrettyString());
        } catch (UserRecoverableAuthIOException e) {
            activity.startActivityForResult(e.getIntent(), StartupActivity.REQUEST_AUTHORIZATION);
        } catch (IOException e) {
            Log.e(TAG, "unable to get the bucket", e);
        }
        return bucket;

    }

    private class BucketTask extends AsyncTask<Account, Void, Bucket> {
        @Override
        protected Bucket doInBackground(Account... params) {



            try {

                if(credential == null) {
                    Account account = params[0];
                    credential = GoogleAccountCredential.usingOAuth2(activity, Collections.singleton(StorageScopes.DEVSTORAGE_READ_ONLY));
                    credential.setSelectedAccountName(account.name);
                }

                if( storage == null && credential != null) {
                    storage = getStorageService();
                }

                return getBucket();


        } catch (Throwable t) {
                Log.e(TAG, "Error while trying to import images from server", t);
            }
            return null;
        }

         @Override
        protected void onPostExecute(Bucket result) {
            //Do something with result
            if (result != null)
                result.getId();
        }
    }
}

I followed the Drive sample.

Any advice ?

Upvotes: 0

Views: 1002

Answers (1)

atali
atali

Reputation: 53

I found out the issue.

Don't use the Simple API Access coming from the API console but you have to setup the Client ID for installed applications (see the Drive SDK link above)

So instead of :

private Storage getStorageService() {

        StorageRequestInitializer storageRequestInitializer = new StorageRequestInitializer(ClientCredentials.API_KEY);

        return new Storage.Builder(transport,
                                    JSON_FACTORY,
                                    credential)
                                    .setApplicationName(APPLICATION_NAME)
                                    .setStorageRequestInitializer(storageRequestInitializer)
                                    .build();
    }

you should use it like this:

private Storage getStorageService() {

        return new Storage.Builder(transport,
                                    JSON_FACTORY,
                                    credential)
                                    .setApplicationName(APPLICATION_NAME)
                                    .build();
    }

Hope that help !

Upvotes: 1

Related Questions