Skip to content
This repository has been archived by the owner on Jan 11, 2022. It is now read-only.

Can't get fileId of selected file from google drive . #106

Closed
himanshiThakur opened this issue Jan 14, 2019 · 19 comments
Closed

Can't get fileId of selected file from google drive . #106

himanshiThakur opened this issue Jan 14, 2019 · 19 comments
Assignees
Labels

Comments

@himanshiThakur
Copy link

Method to open file , here i can only access name and content

private void openFileFromFilePicker(Uri uri) {

    if (mDriveServiceHelper != null) {

        Log.d(TAG, "Opening " + uri.getPath());

        mDriveServiceHelper.openFileUsingStorageAccessFramework(getContentResolver(), uri)
                .addOnSuccessListener(nameAndContent -> {
                    String name = nameAndContent.first;
                    String content = nameAndContent.second;


                    mFileTitleEditText.setText(name);
                    mDocContentEditText.setText(content);



                    // Files opened through SAF cannot be modified, except by retrieving the
                    // fileId from its metadata and updating it via the REST API. To modify
                    // files not created by your app, you will need to request the Drive
                    // Full Scope and submit your app to Google for review.
                    setReadOnlyMode();
                })
                .addOnFailureListener(exception ->
                        Log.e(TAG, "Unable to open file from picker.", exception));
    }
}

Comment : Files opened through SAF cannot be modified, except by retrieving the
// fileId from its metadata and updating it via the REST API. To modify
// files not created by your app, you will need to request the Drive
// Full Scope and submit your app to Google for review.

Please guide me here . How can we get fileId here . I need fileId to download the selected file .

@sqrrrl
Copy link
Member

sqrrrl commented Jan 23, 2019

Rich, could you take a look? Thanks.

@rbstarbuck
Copy link
Contributor

Hmm, it appears that the FileId column is not exposed to third parties by the Drive content provider. My apologies, I didn't realize that this was a 1P-only field. It appears that the proposed workaround for modifying files opened with SAF will not work for external developers. I talked to someone on the Drive app team, this is intentional for security reasons and they will not be exposing the FileId.

@sqrrrl
Copy link
Member

sqrrrl commented Jan 23, 2019

Filed a bug internally to update the migration guide. Will also have to remove the comment from the sample too, so leaving this open.

@sqrrrl
Copy link
Member

sqrrrl commented Jan 23, 2019

I take it this means there really isn't a migration path from the picker component in the deprecated API. That leaves using the full drive scope and rolling your own UI as the only alternative.

@himanshiThakur
Copy link
Author

i want to download the selected file from drive , but until i don't have fileId i can't download file .
I am stuck here , now i can't add google drive as option to upload bills in my app .
Is there any possible solution for this ?

@rbstarbuck
Copy link
Contributor

You should still be able to download metadata and contents for files obtained via SAF, you just can't modify or upload.

@himanshiThakur
Copy link
Author

By using this method
public Task<Pair<String, String>> openFileUsingStorageAccessFramework(ContentResolver contentResolver, Uri uri) {
I can only access name and content (in string) of selected file not fileId . And to download file fileID is required.
Method to download file :
String fileId = "1ZdR3L3qP4Bkq8noWLJHSr_iBau0DNT4Kli4SxNc2YEo";
OutputStream outputStream = new ByteArrayOutputStream();
driveService.files().export(fileId, "application/pdf")
.executeMediaAndDownloadTo(outputStream);

@rbstarbuck
Copy link
Contributor

Please take a look at the DriveServiceHelper#openFileUsingStorageAccessFramework for an example of how to access metadata and stream file contents. You won't be able to get the FileID, but you can retrieve most other metadata and file contents using the mechanism displayed there.

@himanshiThakur
Copy link
Author

himanshiThakur commented Feb 13, 2019

Requirement in my app : upload any doc, file like resume or any bill which user selected , from google drive to server .
but using #openFileUsingStorageAccessFramework i can only get file name . How i am suppose to upload that file, doc on our server unless i didn't get the fileID .

@aleripe
Copy link

aleripe commented Feb 25, 2019

The migration guide still shows incomplete and misleading information. You decided to deprecate the Android API without providing any feasible alternative. This way Android development is going nowhere, we developers can't rewrite our apps every six months without any Google support. I'm really really disappointed.

@adityabhaskar
Copy link

Hi folks,

Since this comment confirms that this sample does not work as a Drive Picker sample, I would suggest highlighting this in a warning at top of the readme.md.

I wasted half a day struggling to get a fileId using this sample's code before discovering this issue. A notice on top of the readme warning not to use this sample for a Drive Picker would help others avoid wasting time.

Cheers!

Adi

@rbstarbuck
Copy link
Contributor

Just updated the comment in the sample app, thanks for the heads-up.

@rbstarbuck
Copy link
Contributor

Hmm and, just realized that the migration guide on developers.google.com wasn't updated. Just sent a request to have the modified guide published to our developer page, but it won't be handled until Monday at the earliest.

@adityabhaskar
Copy link

Thank you, @rbstarbuck!

Is there a process for convincing the Drive/GSuite team on bringing back a native picker functionality?

Perhaps by apps passing an intent to the Drive app, specifying the details (file/folder, mime-type, user and app's auth token), and receiving the chosen file's base details (similar to the files.list or files.get in the Rest API). This would be far preferable to the current scenario of each app implementing its own Drive Picker.

More than the effort, this would reduce the vulnerability by not having to require the DRIVE_FULL permission when DRIVE_FILE would suffice. Implementing the picker ourselves would require DRIVE_FULL just to use the files.list endpoint.

Cheers!

Adi

@shroff
Copy link

shroff commented Mar 11, 2019

Our app needs access to drive file ids to associate them with internal objects.

Is the best/recommended approach really to roll our own drive file picker? It doesn't seem like the best idea in terms of consistency, security, and of course effort involved.

I suppose we could make a copy of the file but that has some obvious issues, not to mention the fact that it doesn't account for virtual files.

Any chance of a first party picker? If not then any other alternatives?

@rbstarbuck
Copy link
Contributor

Unfortunately, there is currently no alternative to implementing your own file picker if the SAF picker doesn't supply the necessary functionality. There were security vulnerabilities in the early versions of Android content providers, so we can't expose create/modify functionality through SAF. Eventually, the minSdk for Drive will move past those vulnerable versions and we'll be able to add those functions. But that won't be for a few years. We didn't receive approval for providing a first-party picker as the point of deprecation was to destaff the project as part of a Drive reorg. Sorry :(

@shroff
Copy link

shroff commented Mar 12, 2019

Gotcha, thanks for the clarification @rbstarbuck

@mattlaabs
Copy link

@rbstarbuck wrote

so we can't expose create/modify functionality through SAF

I don't understand how read access to the driveId is a problem there? Or would it be at least possible to get the driveId on Android OS versions which have these vulnerabilities fixed?

@Kshitij1792
Copy link

Kshitij1792 commented Mar 8, 2020

Not sure if it has been resolved by now or not.

But a workaround could be to get the name of the file from the StorageAccessFramework and then fire the search(fileName) query on drive using proper mimeType to get the Drive->fileId of that file. This would save you from the burden of rolling out your own FilePicker as well as having to require the DRIVE_FULL permission when DRIVE_FILE would suffice.

I used it to download a .zip file using the SAF implementation given on the migration page. Using the fileName returned by SAF and mimeType='application/zip', fired the search query to find it's Drive->fileID. Here is some code.

private String mSearchedZipFileId;
private File mSearchedZipFile;

public Task<String> searchZipFile(String zipFileName) {
    return Tasks.call(mExecutor, () -> {
        String pageToken = null;
        do {
            FileList result = mDriveService.files().list()
                    .setQ("mimeType='application/zip'")
                    .setSpaces("drive")
                    .setFields("nextPageToken, files(id, name)")
                    .setPageToken(pageToken)
                    .execute();
            for (File file : result.getFiles()) {
                System.out.printf("Found file: %s (%s)\n",  file.getName(), file.getId());
                if (file.getName().equals(zipFileName)){
                    mSearchedZipFile = file;
                    Log.e(TAG, "searchZipFile: ID="+file.getId() );
                    break;
                }
            }
            pageToken = result.getNextPageToken();
        } while (pageToken != null);
        return mSearchedZipFile.getId();
    });
}

Hope this helps.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

8 participants