2

I have been facing problem while coding that while using service account key and using drive.files.list API, i am not able to get files, though i have shared all the files publicly

const { google } = require('googleapis');
const drive = google.drive('v3');
const jwtClient = new google.auth.JWT(
    client_email,
    null,
    private_key,
    ['https://www.googleapis.com/auth/drive']
);

jwtClient.authorize(function (err, tokens) {
    if (err) {
        console.log(err);
        return;
    } else {
        console.log("Successfully connected!");
    }
});


// List Drive files.
drive.files.list({
    auth: jwtClient,
    // fields: "files",
    includeRemoved: false,
    spaces: 'drive'
}, (listErr, resp) => {
    if (listErr) {
        console.log(listErr);
        return;
    }
    console.log("Result ========>", resp.data.files)
});
  • In result i am getting nothing though i have shared all the files publicly and given edit rights to all.
  • In service account i have enable google API and gave qwner permission.
  • I want all the publicly share files to list.
  • Where i am wrong in the code.

please help me out in this. thanks :)

Abhi Thakkar
  • 151
  • 4
  • 17

2 Answers2

3

A service account is not you it is a dummy user. As like any user a files.list will only return the files that it has access to. That being files it has created and files someone has shared with it. While one would think that public files everyone has access to. If a files.list returned a list of all the files on Google drive that were set to public that would be a huge list and not very useful.

By setting a file to public if you have the file id you will be able to see it using an API key. You wont be able to edit it but you will be able to do a file.get on it.

Take the service account email address and go to google drive share the folder that contains the files with the service account like you would any other user. You can also share each file individually with the service account if you wish. Then try and do a files.list.

Linda Lawton - DaImTo
  • 106,405
  • 32
  • 180
  • 449
  • but in my app which i am building i want functionality that user can see the public files and download the file from google drive and upload the files to google drive without loggin in to google drive. So how come is that possible If you have any other way to do it, can you please let me know thanks :) – Abhi Thakkar Jun 01 '18 at 08:46
  • Use the service account for everything. The service account has its own drive account. It can upload and download to its own account. No login will be needed. I have a blog post that might help explain this http://www.daimto.com/google-developer-console-service-account/ – Linda Lawton - DaImTo Jun 01 '18 at 08:54
  • but i have used this to upload files, the response says files are uploaded and when i opened my drive, it doesn't appear there So can u please tell me something about it, how can i see the uploaded files. – Abhi Thakkar Jun 04 '18 at 08:14
  • Because the files are uploaded to the service accounts google Drive account not your personal google drive account. There is no web view for a service accounts drive account all access will have to be done though code. Take the service account email address share a folder on your drive account with it. find the folder id and upload to that folder not the service accounts root folder. – Linda Lawton - DaImTo Jun 04 '18 at 08:15
  • thanks @DalmTo for helping me out. One last question, Is it a correct way to integrate google drive account with app? . in my functionaly i want user to integrate their account with a application. if not than can you tell me another way. thanks :) – Abhi Thakkar Jun 04 '18 at 11:29
  • If you want to access the users data then you should be using Oauth2. If your app has static data that you as the developer control you should use a service account. I would say you should probably use Oauth2 – Linda Lawton - DaImTo Jun 04 '18 at 11:35
  • but i do not want user to redirect or login to any website, i want if user integrate his drive with app once than the app have all the rights and than user didn't have to do anything. – Abhi Thakkar Jun 04 '18 at 11:43
  • It doesn't matter. If you want access to the users drive account you must be authenticated. You cant access their data without their permission. They should only need to authenticate once assuming you are storing the refresh token. – Linda Lawton - DaImTo Jun 04 '18 at 11:45
  • I was under the impression that if the respective app was added to the G Suite security console via the "Manage API client access" interface, the app (and its service account) would have access to every user's files. So simple things like file.list would work for all Drive content. – Greg Aug 27 '18 at 02:26
  • 1
    huh. so that *does* work but it requires that i pass in the email of a user i'm trying to delegate to when i create the OAuth client. – Greg Aug 27 '18 at 02:37
0

Sharing a domain-wide Shared Folder with the service account email did not work for me.
But, I did find this article (https://nilsnh.no/2018/12/17/how-to-implement-domain-wide-delegation-in-gsuite-using-node.js) that explained that you can pass an "email address to impersonate" to the subject parameter of the google.auth.JWT call. It is now as if you logged in as that user. You should probably create a specific domain user for this purpose. This dedicated user will not have any personal drive files, but it will allow you to access the domain-wide shared drives without having to use that user's password.

const emailAddressToImpersonate = 'sharedDriveAccess@myworkspacedomain.com'
const jwtClient = new google.auth.JWT(
    client_email,
    null,
    private_key,
    ['https://www.googleapis.com/auth/drive'],
    emailAddressToImpersonate
);
Mike M
  • 71
  • 1
  • 3