8

I get an invalid parent folder error, and I've seen the solutions to use resource ID rather than Drive ID, but it's a different scenario here.

I'm trying to access the AppFolder, and this just uses the GoogleApiClient like so:

this.appFolder = Drive.DriveApi.getAppFolder(mGoogleApiClient);

When I later try to create a file in it, I get the above error.

DriveFolder.DriveFileResult fileResult = appFolder.createFile(mGoogleApiClient, changeSet, driveContentsResult.getDriveContents()).await();

Then fileResult.getStatus() gives me the erros.

This used to work for me before. What's different is that I've manually emptied my app's data on Google Drive (delete hidden app data). But I haven't disconnected the app - so I would assume that appFolder will continue to work the same way...

So far the only workaround is uninstalling the app, but this way I lose my data.

This is reproducible. Please help.

mmagician
  • 1,970
  • 2
  • 15
  • 26
  • Aren't you running into something similar to [this](http://stackoverflow.com/questions/30172915/user-disconnecting-app-in-drive-causes-loss-of-data-under-file-scope)? – seanpj Oct 21 '15 at 03:47
  • I don't think so. First of all, I dont' revoke authorization, I just delete hidden app data - the app is still connected. Second, I don't worry about old files being lost (I wouldn't expect them to be there anyway after disconnecting the app), but rather about creation of new files. I can't create files in the appFolder because of the "invalid parent folder" error. – mmagician Oct 21 '15 at 11:05
  • My WILD guess is that after 'emptying' your app data, you could try to disconnect / connect (I do it in onPause/onResume to make sure GooPlaySvcs are still in business) and try to grab the value of 'appFolder' again. You may try to look at the appFolder's DriveId value (getAppFolder(mGAC).getDriveId()) before and after the 'emptying' action. But as I said it is a LONG shot. – seanpj Oct 21 '15 at 11:44
  • Thanks, I will try this – mmagician Oct 22 '15 at 13:55
  • This is still happening May 2016. Has anyone found a work-around or a solution? With the possibility that this issue has not been addressed, I have filed this as a defect as [Issue 4483](https://code.google.com/a/google.com/p/apps-api-issues/issues/detail?id=4483&thanks=4483&ts=1462397034) with the apps-api-issues project. @seanpj – Cheticamp May 10 '16 at 18:56
  • @Cheticamp I am more fortunate than you by the fact that I have retired some time ago and do not have to deal with this anymore. Lucky me and unfortunate to those I could help to fight Google's luck of responsibility for their own products. – seanpj May 14 '16 at 06:00
  • It looks like this problem was resolved as of Jan. 9, 2017. See comments on [Issue 4483](https://code.google.com/a/google.com/p/apps-api-issues/issues/detail?id=4483&thanks=4483&ts=1462397034) at the apps-api-issues project for details. – Cheticamp Jan 13 '17 at 15:51

4 Answers4

4

Update: This issue, #4483, was fixed in January 2017. The following fix may not apply anymore.

Since this continues to be an outstanding issue, I have taken steps to establish a work-around that can be done with code without resorting to user intervention.

As @seanpj says, this issue does not always occur and seems to be dependent upon the sync status of the Drive service. However, if the problem does occur, the following method works for me to circumvent the problem. I post it here in case it may be helpful to someone else. The Javadoc has more information.

/**
 * Works around the Drive API for Android (GDAA) issue where the appDataFolder becomes
 * unavailable after hidden app data is deleted through the online Drive interface
 * (Settings->Manage Apps->Delete hidden app data) by using the REST v3 API to create an
 * empty file in appDataFolder. The file is immediately deleted after creation but leaves
 * the appDataFolder in working order.
 * See <a href="https://code.google.com/a/google.com/p/apps-api-issues/issues/detail?id=4483"
 * target="_blank">apps-api-issues #4483</a>
 * <p>
 * Call this method after a call to the Drive API fails with error code 1502
 * (DriveStatusCodes.DRIVE_RESOURCE_NOT_AVAILABLE) when dealing with the appDataFolder then
 * try the failed operation again.
 * <p>
 * This method assumes that all appropriate permissions have been granted and authorizations
 * made prior to invocation.
 *
 * @param context - Context
 * @param account The account name that has been authorized, e.g., someone@gmail.com.
 * @throws IOException From the REST API.
 */
private void fixAppDataFolder(Context context, String account) throws IOException {
    final String[] SCOPES = {DriveScopes.DRIVE_APPDATA};
    GoogleAccountCredential credential = GoogleAccountCredential.usingOAuth2(
            context, Arrays.asList(SCOPES)).setBackOff(new ExponentialBackOff());
    HttpTransport transport = AndroidHttp.newCompatibleTransport();
    JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
    com.google.api.services.drive.Drive driveService;

    credential.setSelectedAccountName(account);
    driveService = new com.google.api.services.drive.Drive.Builder(
            transport, jsonFactory, credential)
            .setApplicationName("Your app name here")
            .build();

    File fileMetadata = new File();
    fileMetadata.setName("fixAppDataFolder")
            .setMimeType("text/plain")
            .setParents(Collections.singletonList("appDataFolder"));

    File appDataFile = driveService.files()
            .create(fileMetadata)
            .setFields("id")
            .execute();

    driveService.files().delete(appDataFile.getId()).execute();
} // fixAppDataFolder
Cheticamp
  • 61,413
  • 10
  • 78
  • 131
3

Although this does not solve your problem, your question got me interested, so I ran a little test using this demo (follow "appfolder" in this code). Here's what I learned:

First, I could reproduce your problem using the following sequence

1/ getAppFolder(mGAC)  
2/ create folder DEMOROOT in app folder
3/ create folder 2015-10 in DEMOROOT  
4/ create file with content in 151022-075754 in 2015-10  

5/ list full tree ... result \DEMOROOT\2015-10\151022-075754  
6/ read content of 151022-075754 ... OK

so far so good. Without disconnecting, I go to

drive.google.com > Settings > Manage Apps > Options > Delete hidden app data

Now, there should be no objects in the app folder, I run:

1/ getAppFolder(mGAC)  
2/ list full tree ... result \DEMOROOT\2015-10\151022-075754  
3/ read content of 151022-075754 ... FAIL

As you can see, in my situation the getAppFolder(mGAC) returns valid DriveFolder (DriveId) that can be used. Even the DriveId string looks the same. Listing of folders/files returns valid objects. It is not supposed to, but I know there is a latency I have to count on, so the list result may change later to reflect the deletion. Attempt to read the file content fails.

A few minutes later (GDAA probably synchronized), the same attempt to list fails, still understandable result, but another attempt to create any object (folder/file) in app folder fails with 'invalid parent folder' error as you pointed out. Disconnect / re-connect does not help, so the app is toasted.

This points to a serious bug that should be addressed. Again the same as in SO 30172915, an uneducated user's action can cause irreparable damage - loss of data to the Android App with no known remedy.

Community
  • 1
  • 1
seanpj
  • 6,735
  • 2
  • 33
  • 54
  • Because you have participated in a number of discussions regarding GDAA bugs, I'd like to ask you: Is there an issue tracking website for GDAA or Google Play Services? I've seen indications that Play Services bug reports are not welcome at the AOSP issue tracker site. The only place I've found for reporting problems is the [Help Forum](https://productforums.google.com/forum/#!topicsearchin/drive/category$3Areport-a-problem%7Csort:relevance%7Cspell:false). – Bob Snyder Nov 21 '15 at 19:06
  • 1
    I have run into [this](https://code.google.com/a/google.com/p/apps-api-issues/issues/list?q=label:API-DriveAndroid) some time ago, but I have never been active there. I rely on StockOverflow as my main source. It looks like Google uses SO as a convenient place to pick-and-choose problems they want to deal with and ignore [others](http://stackoverflow.com/questions/23073474/google-drive-android-api-changeevent-listener-workings). Although many 'problems' are just badly documented architectural (built in) issues. It just takes time to understand the limitations of both GDAA and the REST Apis. – seanpj Nov 22 '15 at 02:21
  • Hi seanpj, I can confirm your finding. Do you plan to file an official bug report? – Cheok Yan Cheng Jan 13 '16 at 17:15
  • No, as per comment ['Just a side note...' here](http://stackoverflow.com/questions/34705929/filters-ownedbyme-doesnt-work-in-drive-api-for-android-but-works-correctly-i) . – seanpj Jan 13 '16 at 17:38
1

I am experiencing the same problem. I thought GoogleApiClient.ClearDefaultAccountAndReconnect() might be a workaround but it didn't help. As an alternative to uninstalling/reinstalling the app you can try these steps, they worked for me:

  1. In a browser, go to the page for managing your Google account's security settings.
  2. Select "Connected apps & sites", then "Manage Apps"
  3. Select your app from the list. It will show that it has access to Google Drive and a Remove button.
  4. Click on Remove.
  5. Wait a minute or two for the change to take effect, then run your app.
  6. When your app attempts to connect to Drive, you should get the consent screen prompting the user to allow or deny access. Accepting will reauthorize the app and should clear the problem. It did for me.
Bob Snyder
  • 37,759
  • 6
  • 111
  • 158
1

This bug was reported to google on May 4th:

https://code.google.com/a/google.com/p/apps-api-issues/issues/detail?id=4483

As a workaround you can use the REST API.

AsterixR
  • 547
  • 7
  • 9