Google Drive API Authentication Issues

Working solution for newer Android versions:

String authToken = GoogleAuthUtil.getToken(context, userEmail, "oauth2:" + DriveScopes.DRIVE);

This approach works perfectly and allows me to build my Drive service and interact with Google Drive API. However, this method only works on Android 2.2+. My app needs to support Android 2.1 as well.

Alternative approach for older Android versions:

AccountManager manager = AccountManager.get(this);
Bundle params = new Bundle();
manager.getAuthToken(
    userAccount,
    "oauth2:" + DriveScopes.DRIVE,
    params,
    this,
    new TokenCallback(this),
    null);

This code successfully retrieves a token, but when I use it to build my Drive service, the API calls fail. For instance, when I try:

driveService.files().list().setQ("trashed=false and name='myFile'").execute();

I get this 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"
}

My Drive service setup:

HttpTransport transport = new NetHttpTransport();
JacksonFactory factory = new JacksonFactory();
Drive.Builder builder = new Drive.Builder(transport, factory, null);
builder.setJsonHttpRequestInitializer(new JsonHttpRequestInitializer() {
    public void initialize(JsonHttpRequest req) throws IOException {
        DriveRequest driveReq = (DriveRequest) req;
        driveReq.setPrettyPrint(true);
        driveReq.setKey(API_KEY);
        driveReq.setOauthToken(authToken);
        driveReq.setEnableGZipContent(true);
    }
});

driveService = builder.build();

Your problem is mixing API key auth with OAuth token auth in the Drive service setup - they don’t work together. Drop the setKey() call completely when using OAuth. Also, AccountManager tokens need proper credential wrapping. Skip the JsonHttpRequestInitializer and build your service like this: java GoogleCredential credential = new GoogleCredential(); credential.setAccessToken(authToken); Drive service = new Drive.Builder(transport, factory, credential).build(); I’ve used this setup for Android 2.1 support and it’s solid. Your AccountManager token is fine, but the service builder can’t handle it the way you’ve got it configured.

Had the same authentication nightmare with older Android versions. Your AccountManager setup isn’t formatting the token correctly - that’s why you’re getting 401s. When you grab a token with AccountManager.getAuthToken(), it’s raw OAuth that won’t work with setOauthToken() in DriveRequest. Skip that entirely and use GoogleCredential instead: java GoogleCredential credential = new GoogleCredential().setAccessToken(authToken); Pass this credential straight to your Drive.Builder constructor. Don’t mess with JsonHttpRequestInitializer. The Drive API expects “Bearer” in the Authorization header, which GoogleCredential adds automatically but setOauthToken() doesn’t. Fixed my Android 2.1 issues completely. Your token’s fine - just needs the right wrapper.

you’re probably using the wrong auth scope. i ran into the same thing - AccountManager sometimes gives back tokens with different scopes than GoogleAuthUtil. print out both token strings and compare them, they’re likely formatted differently. also, that API_KEY in your DriveRequest might be messing with oauth. try removing the setKey() call.

This topic was automatically closed 4 days after the last reply. New replies are no longer allowed.