1

My Android app updates a Google Drive document. The file can be modified also elsewhere (e.g. through Drive web interface), so there may be a conflict on file upload. However, this should rarely happen. That's why I don't want my app to first query the revision history (since this is in most cases unnecessary) and only after that, update the file. How can I detect that there is a conflict when updating the file?

My investigation so far reveals that getHeadRevisionId() returns null although the null head revision id has been reported fixed. Another thing I tried was setEtag() on the file before update(). It should have given me error on update, but the upload was successful even the file had been changed remotely! Is this the correct way to use ETag?

Community
  • 1
  • 1
Juuso Ohtonen
  • 8,826
  • 9
  • 65
  • 98

2 Answers2

2

Set the If-Match HTTP header:

final Update update = mService.files().update(mDriveFile.getId(), mDriveFile, byteContent);
final HttpHeaders headers = update.getRequestHeaders();
headers.setIfMatch(mDriveFile.getEtag());
update.setRequestHeaders(headers);
mDriveFile = update.execute();

In case the document has changed meanwhile, the update will get rejected with a response something like:

com.google.api.client.googleapis.json.GoogleJsonResponseException: 412 Precondition Failed
{
  "code": 412,
  "errors": [
    {
      "domain": "global",
      "location": "If-Match",
      "locationType": "header",
      "message": "Precondition Failed",
      "reason": "conditionNotMet"
    }
  ],
  "message": "Precondition Failed"
}

Note that ETag might change even if the content does not.

Community
  • 1
  • 1
Juuso Ohtonen
  • 8,826
  • 9
  • 65
  • 98
  • How to use this approach on v3? There was an [File.getEtag() in v2](https://developers.google.com/resources/api-libraries/documentation/drive/v2/java/latest/com/google/api/services/drive/model/File.html#getEtag()), but it's [gone in v3](https://developers.google.com/resources/api-libraries/documentation/drive/v3/java/latest/). – surlac Dec 13 '16 at 23:42
1

"Is this the correct way to use ETag?"

Yes

Also, for non-Docs files, you should also check md5Checksum for changes to the content.

pinoyyid
  • 21,499
  • 14
  • 64
  • 115
  • So, if it was the correct way to use ETag, why didn't my file update fail? – Juuso Ohtonen Feb 16 '14 at 09:03
  • Can you paste the http request and response. – pinoyyid Feb 16 '14 at 13:57
  • My suspicion is that setEtag() is not setting the If-Match header. You will probably need to set it manually. Seeing the http request should confirm this. – pinoyyid Feb 17 '14 at 04:24
  • A couple of questions: 1. How do I log the headers (tried http://stackoverflow.com/a/3303131/1097104 without success)? 2. How do I set the headers manually, can I somehow set it as part of my mService.files().update(...).execute() command? – Juuso Ohtonen Feb 22 '14 at 06:13
  • 1
    (1) see http://code.google.com/p/google-http-java-client/wiki/Android#Logging (2) The Java client library gives you access to the underlying http transport. I can't find a quick link to paste for you. This is actually a good topic for a separate SO question. – pinoyyid Feb 22 '14 at 06:39
  • 1. Thanks, now I'm able to log HTTP headers. 2. I followed your advice and asked a separate question http://stackoverflow.com/q/21968822/1097104 – Juuso Ohtonen Feb 23 '14 at 13:31
  • I don't see ETag in [v3](https://developers.google.com/drive/v3/reference/files#resource). What to use for "if-match" header to detect conflict in v3? – surlac Dec 13 '16 at 23:39