googleapis / google-api-nodejs-client

Google's officially supported Node.js client library for accessing Google APIs. Support for authorization and authentication with OAuth 2.0, API Keys and JWT (Service Tokens) is included.
https://googleapis.dev/nodejs/googleapis/latest/
Apache License 2.0
11.42k stars 1.92k forks source link

google.drive.files.list v3 parameters ignored? #1011

Closed fabioneves closed 6 years ago

fabioneves commented 6 years ago

Hey!

I'm trying to get files from my google drive, but looks like the v3 parameters are completely ignored, even if I send a 'pageSize' of 1, I always get 100 results. When I specify fields to get additional data from the files I always get the same 4 fields: kind, id, name and mimeType.

Simple call:

const gdrive = google.drive('v3');

gdrive.files.list({
    auth: authClient,
    pageSize: 1
}

Using googleapis 26.0.1 (also tried with 25).

Thanks!

jongcs commented 6 years ago

Same problem here. The 'q' parameter does not work.

mathemagics commented 6 years ago

having the same issue with calendar.events.list

fabioneves commented 6 years ago

On drive v2 api the parameters work just fine. When testing online on google's site testbox, the parameters work fine, so it's not an issue on google's api, but probably the nodejs module.

molobala commented 6 years ago

The same here :(

samaystops4no1 commented 6 years ago

@fabioneves For me, the pageSize parameter seems to work. These are the details of my code and environment.

Node Version: 8.9.4 googleapis node.js client version: 26.0.1

Code -

var { google } = require('googleapis');
var OAuth2 = google.auth.OAuth2;

var oauth2Client = new OAuth2(
  "YOUR APP ID",
  "YOUR APP SECRET",
  "YOUR REDIRECT URI"
);

var googleAuth = {
  access_token: "YOUR ACCESS TOKEN",
  token_type: 'Bearer'
}

oauth2Client.setCredentials(googleAuth);

var drive = google.drive({ version: 'v3' });

drive.files.list({
  auth: oauth2Client,
  pageSize: 1
}, function (err, resp) {
  if (err) {
    console.log("ERROR", err);
  }
  else {
    console.log(resp.data.files.length);
  }
});
samaystops4no1 commented 6 years ago

@jongcs I tried using the 'q' parameter and it is working well. Can you please share your code?

jongcs commented 6 years ago

@samaystops4no1 I just follow the quickstart guide. 'q' and 'pageSize' are not working for me.

googleapis version: 26.0.1 node.js versioin: 9.6.1 (8.9.4 not working too)

function listFiles(auth) {
  var service = google.drive('v3');
  service.files.list({
    auth: auth,
    pageSize: 10,
    q: "'MY GOOGLE DRIVE FOLDER ID' in parents and trashed = false",
    fields: "nextPageToken, files(id, name)"
  }, function(err, response) {
    if (err) {
      console.log('The API returned an error: ' + err);
      return;
    }
    var files = response.files;
    if (files.length == 0) {
      console.log('No files found.');
    } else {
      console.log('Files:');
      for (var i = 0; i < files.length; i++) {
        var file = files[i];
        console.log('%s (%s)', file.name, file.id);
      }
    }
  });
}
samaystops4no1 commented 6 years ago

@jongcs I tried your exact query and it is working well for me. I think the problem is with the callback that you are passing in the google node client. The response.files is actually undefined and it should be response.data.files

Please try this code and inform if you still face problems.

function listFiles(auth) {
  var service = google.drive('v3');
  service.files.list({
    auth: auth,
    pageSize: 10,
    q: "'MY GOOGLE DRIVE FOLDER ID' in parents and trashed = false",
    fields: "nextPageToken, files(id, name)"
  }, function(err, response) {
    if (err) {
      console.log('The API returned an error: ' + err);
      return;
    }
    var files = response.data.files;
    if (files.length == 0) {
      console.log('No files found.');
    } else {
      console.log('Files:');
      for (var i = 0; i < files.length; i++) {
        var file = files[i];
        console.log('%s (%s)', file.name, file.id);
      }
    }
  });
}
JustinBeckwith commented 6 years ago

Apologies for the problems folks. You're absolutely right - you need to check for response.data to get the full response here.

You can see a full working sample here: https://github.com/google/google-api-nodejs-client/blob/master/samples/drive/list.js

Hope this helps!

philcal commented 6 years ago

This issue does not appear to be resolved. I too am following the Quickstart Guide.

My code returns response.files, not response.data.files so the quickstart guide is correct, however pageSize is ignored (and possibly q as well).

Perhaps there is an issue with the version of the underlying http client (request@2.85.0 or axios@0.18.0)?

function listFiles(auth) {
  var service = google.drive('v3');
  service.files.list({
    auth: auth,
    pageSize: 10,
    fields: "nextPageToken, files(id, name)"
  }, function(err, response) {
    if (err) {
      console.log('The API returned an error: ' + err);
      return;
    }
    if (response.files) {
      console.log(`response.files=${response.files.length} records`);
    } else {
      console.log(`missing response.files`);
    }
    if (response.data) {
      console.log(`response.data.files=${response.data.files.length} records`);
    } else {
      console.log(`missing response.data`);
    }
  });
}

Output is:

response.files=100 records
missing response.data

package.json is:

{
  ...
  "dependencies": {
    "google-auth-library": "^0.12.0",
    "googleapis": "^27.0.0"
  },
  ...
}

Any help would be appreciated.

JustinBeckwith commented 6 years ago

Greetings! Please remove google-auth-library from your package.json, run 'npm install', and try again :)

philcal commented 6 years ago

@JustinBeckwith Many thanks, I think that worked.

I also updated the quickstart code to suit the new API:

var fs = require('fs');
var readline = require('readline');
var {google} = require('googleapis');
var urlshortener = google.urlshortener('v1');

// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/drive-nodejs-quickstart.json
var SCOPES = ['https://www.googleapis.com/auth/drive.metadata.readonly'];
var TOKEN_DIR = (process.env.HOME || process.env.HOMEPATH ||
    process.env.USERPROFILE) + '/.credentials/';
var TOKEN_PATH = TOKEN_DIR + 'drive-nodejs-quickstart.json';

// Load client secrets from a local file.
fs.readFile('client_secret.json', function processClientSecrets(err, content) {
  if (err) {
    console.log('Error loading client secret file: ' + err);
    return;
  }
  // Authorize a client with the loaded credentials, then call the Drive API.
  authorize(JSON.parse(content), listFiles);
});

/**
 * Create an OAuth2 client with the given credentials, and then execute the
 * given callback function.
 *
 * @param {Object} credentials The authorization client credentials.
 * @param {function} callback The callback to call with the authorized client.
 */
function authorize(credentials, callback) {
  var clientSecret = credentials.installed.client_secret;
  var clientId = credentials.installed.client_id;
  var redirectUrl = credentials.installed.redirect_uris[0];

  var OAuth2 = google.auth.OAuth2;
  var oauth2Client = new OAuth2(clientId, clientSecret, redirectUrl);

  // Check if we have previously stored a token.
  fs.readFile(TOKEN_PATH, function(err, token) {
    if (err) {
      getNewToken(oauth2Client, callback);
    } else {
      oauth2Client.credentials = JSON.parse(token);
      callback(oauth2Client);
    }
  });
}

/**
 * Get and store new token after prompting for user authorization, and then
 * execute the given callback with the authorized OAuth2 client.
 *
 * @param {google.auth.OAuth2} oauth2Client The OAuth2 client to get token for.
 * @param {getEventsCallback} callback The callback to call with the authorized
 *     client.
 */
function getNewToken(oauth2Client, callback) {
  var authUrl = oauth2Client.generateAuthUrl({
    access_type: 'offline',
    scope: SCOPES
  });
  console.log('Authorize this app by visiting this url: ', authUrl);
  var rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
  });
  rl.question('Enter the code from that page here: ', function(code) {
    rl.close();
    oauth2Client.getToken(code, function(err, token) {
      if (err) {
        console.log('Error while trying to retrieve access token', err);
        return;
      }
      oauth2Client.credentials = token;
      storeToken(token);
      callback(oauth2Client);
    });
  });
}

/**
 * Store token to disk be used in later program executions.
 *
 * @param {Object} token The token to store to disk.
 */
function storeToken(token) {
  try {
    fs.mkdirSync(TOKEN_DIR);
  } catch (err) {
    if (err.code != 'EEXIST') {
      throw err;
    }
  }
  fs.writeFile(TOKEN_PATH, JSON.stringify(token));
  console.log('Token stored to ' + TOKEN_PATH);
}

/**
 * Lists the names and IDs of up to 10 files.
 *
 * @param {google.auth.OAuth2} auth An authorized OAuth2 client.
 */
function listFiles(auth) {
  var service = google.drive('v3');
  service.files.list({
    auth: auth,
    pageSize: 2,
    fields: "nextPageToken, files(id, name)"
  }, function(err, response) {
    if (err) {
      console.log('The API returned an error: ' + err);
      return;
    }
    var files = response.data.files;
    if (files.length == 0) {
      console.log('No files found.');
    } else {
      console.log('\nFiles:');
      for (var i = 0; i < files.length; i++) {
        var file = files[i];
        console.log('%s (%s)', file.name, file.id);
      }
    }
  });
}
JustinBeckwith commented 6 years ago

Thank you :)

fabioneves commented 6 years ago

Tested @philcal, worked! Thanks

vbunjes commented 6 years ago

@philcal This works now with this example code, weird this is not yet fixed on the google quick start