I'm willing to add some kind of Google Drive synchronization to my (native) android app - no backend involved (everything will happen in the app).
As seen in the Google Identity documentation, I'm using an AuthorizationClient to get an access token through the AuthenticationResult :
List<Scopes> requestedScopes = Arrays.asList(DriveScopes.DRIVE_APPDATA);
AuthorizationRequest authorizationRequest = AuthorizationRequest.builder().setRequestedScopes(requestedScopes).build();
Identity.getAuthorizationClient(this)
.authorize(authorizationRequest)
.addOnSuccessListener(
authorizationResult -> {
if (authorizationResult.hasResolution()) {
// Access needs to be granted by the user
PendingIntent pendingIntent = authorizationResult.getPendingIntent();
try {
startIntentSenderForResult(pendingIntent.getIntentSender(), REQUEST_AUTHORIZE, null, 0, 0, 0, null);
} catch (IntentSender.SendIntentException e) {
Log.e(TAG, "Couldn't start Authorization UI: " + e.getLocalizedMessage());
}
} else {
// Access already granted, continue with user action
saveToDriveAppFolder(authorizationResult);
}
})
.addOnFailureListener(e -> Log.e(TAG, "Failed to authorize", e));
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == MainActivity.REQUEST_AUTHORIZE) {
AuthorizationResult authorizationResult = Identity.getAuthorizationClient(this).getAuthorizationResultFromIntent(data);
saveToDriveAppFolder(authorizationResult);
}
}
And then, building a Drive instance from it:
Drive.Builder(
GoogleNetHttpTransport.newTrustedTransport(), GsonFactory.getDefaultInstance(),
HttpCredentialsAdapter(GoogleCredentials.create(AccessToken(authorizationResult.getAccessToken(), null)))
).build()
So far, so good, everything is working fine but since AuthorizationResult doesn't contains any refresh token - how am I supposed to handle the expiration of the access token? The app is supposed to sync in the background without any user interactions, so I'm not going to launch the authorization flow again (unless revoked of course).
I'm aware getServerAuthCode() could be sent to your backend to request a pair of access/refresh tokens for server-side access but I don't need (or even want) to access my user's data server-side.
Am I missing something?
-
Hi, may I know, how long you need to test, till authorizationResult.hasResolution() will return true for the 2nd time, after access granted by user? Previously, we are using GoogleSignInClient.silentSignIn to prevent the access token from being expired. But, I am not sure this time - stackoverflow.com/questions/79259001/…Cheok Yan Cheng– Cheok Yan Cheng2025年01月17日 02:00:20 +00:00Commented Jan 17, 2025 at 2:00
-
I didn't tested much but it's been 8 days so far and it didn't returned true yet. I haven't called any API yet with that token since I switched to some other tasks in the meantime - but my wild guess is that calling authorize is renewing the token if needed.Renaud Cerrato– Renaud Cerrato2025年01月17日 06:23:53 +00:00Commented Jan 17, 2025 at 6:23
-
I guess so, because there is no longer silent sign in API. The culprit is, some users have outdated Google Play services. This will cause the new API broken.Cheok Yan Cheng– Cheok Yan Cheng2025年01月17日 06:34:34 +00:00Commented Jan 17, 2025 at 6:34
1 Answer 1
If you need to obtain a refresh token, you need to do the following:
- In the AuthorizationRequest, you also need to set requestOfflineAccess(YOUR-SERVER-CLIENT-ID). This results in getting back not only an access token, but also an authorization code (AuthCode).
- This AuthCode can be exchanged for a new access token and a refresh token. This can be done on your mobile device; it is a relatively simple HTTP request, see this for example.
Note that refresh token is something that needs to be closely safe-guarded. You may want to use PKCE for that reason. Hope that helps.
8 Comments
authorize : the access token changes so it seems to be refreshed, no UI prompt. Calling authorize many times consecutively returns the same token though, so the refresh is handled by the system, caching the last token until expiry. Would be nice someone from the Google Identity team confirm.Explore related questions
See similar questions with these tags.