Why can't I see the files my code has uploaded to Google Drive? - google-drive-api

I have code that uses the Google Drive v3 SDK.
I have a regular (free) Gmail account, and have created a service account. I created a folder in my Google Drive space and shared it with the service account. Lots of kudos to Linda Lawton, whose tutorials are waaay better than the Google docs!
My code uses the Id of the shared folder as its root, and can upload files to the folder and download them again. However, if I look in Google Drive in my browser when signed in with my regular account, the shared folder is empty.
When I upload files, I set a permission of anyone for the Reader role, so that shouldn't be the issue.
Can anyone explain why I can't see the files? I know that the service account has its own GD space, but I'm using the shared folder, which is in my GD space, not the service account's, so I expected to see the files.
Update I'm pretty sure the problem is that the permissions are not being set correctly on the files. I'm doing the following...
Permission permission = new() { Role = "reader", Type = "anyone" };
await _service.Permissions.Create(permission, fileId);
Note that this uses the .NET SDK, but I don't think that should make a lot of difference, the code is almost identical in (say) Java.
I added a call to query the permissions on a file that my script had uploaded, and got the following two...
Type: anyone, Role: reader, Kind: drive#permission, Email:
Type: user, Role: owner, Kind: drive#permission, Email:
The first permission comes from the code shown above. The second one is from when I tried setting a permission for the Gmail account. It seems to have set the permission, but not stored the email address.
Either way, I would have expected that the first permission would have been enough to allow the Gmail account to see them from a browser.
Thanks

Well, after many hours of banging my head against the screen, I finally realised that when I created the top-level folder, I forgot to specify the shared folder, so my code was creating its folders and files in the service account's drive space, not in the shared folder.
I set the correct parent folder, and all works fine now! Don't know if this will ever help anyone, but I'll leave the question and this answer in case it does.

Related

Google Drive API: Edit shared files using a less scary scope

I need to edit Google Drive files created with my nodeJs webapp and owned by me or shared with me.
Using "https://www.googleapis.com/auth/drive/file" scope I can edit files owned by me.
To edit also files shared with me I must use "https://www.googleapis.com/auth/drive" scope. But this scope sends a very scary message to users on login: "This wil allow xxx to: see, edit or delete all of your Google Drive files" (bold is mine).
I don't want to delete your files and I don't want to edit all of your files: is there a way to reach my goal with a less scary scope?
The only alternative to the drive scope, if you want to edit the files, is drive.file, which gives access to files that you have opened or created with the app (ref).
Since this is not an option for you, I'm afraid you'll have to use the scary scope.
Feature request:
Considering your situation, I think you might be interested in this Feature Request, regarding the possibility to restrict access to a specific folder. I think that could be very useful for you if it got implemented. I'd suggest you to star that issue, both to keep track of its development and to help prioritize its implemenation:
Drive Restrict access to folder when authorizing applications
Related:
Google Drive API: 404 when accessing file someone else created
Google Sheet OAuth scopes to only access a few files?

Google Drive API permission to children files

We would like access to a client’s folder within their Google Drive and all files under that folder. This can either be a folder we create from the app or a folder the client picks.
The first approach I tried was to create the folder from the app.
The problem is that I am only able to list the folder itself, but NONE of the content. https://developers.google.com/drive/api/v3/folder
The second approach was to use the Google Picker API. There the
client can choose which folder(s) to give us access to. However we
can only get access to the folder, and none of the children
folders/files. https://developers.google.com/picker/docs
This seemed like an easy and straightforward use case. But can’t seem to find a solution in their documentation, or maybe I don’t comprehend some of the logic. A solution would be a way to either propagate the permission to all the files included in the folder it get’s picked or created… or to have the picker select all the children.

My preference is to continue with the Recommended scope https://www.googleapis.com/auth/drive.file . And it might be that the folder contains thousands of individual files multiple levels in, so it’s not a solution to manually pick the files. Any thoughts on this would be greatly appreciated, thank you!
A possible solution for your situation...
Is to create the folder in a shared drive.
Therefore, even though new files are added/updated/removed you will still be able to see all the updates and retrieve the information needed as you will have constant access to this folder.
Another solution which is more cumbersome...
Is to ask for user's permission and to re-authorize the application each time they are using it so in the case a new file is added you will have access to it.
Reference
Drive API v3 shared drives;
Drive API v3 manage shared drives.
The first approach I tried was to create the folder from the app. The problem is that I am only able to list the folder itself, but NONE of the content. https://developers.google.com/drive/api/v3/folder
The issue is probably the scope you authorized the user with. If you authorized with read only access your not going to be able to create you need full drive access to do that.
If you are using https://www.googleapis.com/auth/drive.file then you should create a folder with that and then create a file in the folder that i believe should work.
The second approach was to use the Google Picker API. There the client can choose which folder(s) to give us access to. However we can only get access to the folder, and none of the children folders/files. https://developers.google.com/picker/docs
There is no way to request access for a single folder or files. Its all or nothing really unless you use the https://www.googleapis.com/auth/drive.file scope which would only give you access to the files that your application created.

googleapi: 403: The download quota for this file has been exceeded. Creds are good, file is new

Please note, this issue seems unique from other "quota exceeded" issues I've seen. It's not bad creds, and it's not a file that has been downloaded a lot.
2020/02/21 15:44:49 ERROR : test.mkv: Failed to copy: multpart copy: failed to open source: open file failed: googleapi: Error 403: The download quota for this file has been exceeded., downloadQuotaExceeded
I'm only receiving this error through the API.
Other files in this shared drive are accessible with the same credentials.
This doesn't affect the file for other users (ie: I tested with an actual Google account [rather than a Service Account] and was able to download the file via the UI.
So what can be going on? I'm used to 403s with Google APIs when the user doesn't have permission, and have even seen this "reason" in a scenario where I just hadn't granted permissions yet. But in this case, the permissions seem just fine [they're all set at the Drive level, anyway].
Important context:
The files that are having this problem were copied from... public sources. Those files likely have exceeded their download quota. But these are copies that I made into my own drive.
To be more speciic, I have copied files into my Drive via the web UI and these files have never presented an issue.
However, these new files that are having issues - I copied them via the Drive API. But they say they're owned by my Service Account, and I can't find ANY linkage back to the original file they were copied from. Just like when I copy them by hand, they have their own file IDs, different than the ones they were copied from.
Things I'm suspicious of:
Maybe the copy performed via the UI, and the copy performed by the API are somehow different?
Somehow my "copy" of the file is more strongly linked to the original file I copied from originally?
Otherwise, I'm out of ideas. Any suggestions would be highly appreciated.
EDIT:
Manual copy method: File file, add star to it, navigate to Drive web ui, go to Starred items, right-click on the file, "Make a Copy".
New API method: use Rust to do this:
let url = format!("https://www.googleapis.com/drive/v3/files/{}/copy", file_id);
let auth_hdr_val = format!("Bearer {}", token.as_str());
let mut query_params = HashMap::new();
query_params.insert("supportsAllDrives", true);
query_params.insert("supportsTeamDrives", true);
let mut body = HashMap::new();
body.insert("parents", [destination_parent_dir]);
client
.post(&url)
.query(&query_params)
.header(reqwest::header::AUTHORIZATION, auth_hdr_val)
.json(&body)
.send()
Nothing too wild, just calling the v3 drive copy API, with a parent directory specified which is a Shared Drive. (Seems like it also happens if I API copy to my drive first, then manually move to Shared Drive.)
Google Drive has undocumented API limits. It appears that one of them is a per-user, per-file limitation.
I switched the service account that I was using to download the particularly problematic files, and they downloaded successfully.
It appears that the "new" method was not the problem, but rather that another service was indexing "new" files in Google Drive and bumped up against this limit. The service account used for downloading was shared with the one indexing.
So, avoid hitting these limits, or use different service accounts for different roles, etc.
I know you found a workaround for your issue, but it seems the issue you were having, it was previously reported by other people on Issue Tracker:
"downloadQuotaExceeded": The download quota for this file has been exceeded..
Receiving downloadQuotaExceeded error in python client.
You can hit the ☆ next to the issue number in the top left on this page as it lets Google know more people are encountering this and so it is more likely to be seen to faster.

drive.file scope and template files

I want to make my application use a limited scope in Google Drive, namely drive.file.
With this scope if I want to create a new file in the drive, by copying an existing file from another user, which has the permission 'anyone with the link' as read, the copy fails.
This has already been asked a few years ago, but the possibilities seems to have narrowed since, as the suggestion of an application owned account seems now deprecated : all links on application owned accounts are broken.
Question: Is there a means of having an application using the limited scope drive.file, while still creating its files by copying them from a file shared for reading, using some sort of service account ?
Try adding read-write access to file metadata by authorizing with the following scopes:
https://www.googleapis.com/auth/drive.metadata
https://www.googleapis.com/auth/drive.metadata.readonly
This related SO post suggests the same.

Get file list from google drive public folder shared by link via API

I'm trying to create script to download all files from another user shared folder in google drive using rest api. If i'm right, there are two variants:
Using drive.children.list, with folder ID
Using drive.files.list, with search query like 'FOLDER_ID in parents'
But both of this variants returning only files which were once opened by my google account in browser. If I open file in browser - this file will appear in results of API calls.
Folder is shared for anyone, who has link.
Where is the problem, how I can list all files in folder?
Since you did not give us any info about the SCOPE, I am wild-guessing that it may be your problem. You probably have FILE scope, instead of DRIVE.
Also, I would recommend to test these things with 'TryIt!' here. You can quickly modify both scopes and queries there.
Good Luck
This is a bug/quirk in the Drive API, though there is an easy workaround. If you call files.update with 'addParents=root' it'll add the shared folder under 'My Drive'. This has the effect of making the files part of your corpus and they'll appear in results.