0
votes

I'm trying to store some of my Electron app's user data into the user's Google Drive. I'm using the 'google-auth-library' and 'googleapis' npm packages and trying to use OAuth2 protocol, but I receive this error: 'The API returned an error: Error: Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup.'

I followed the steps from https://developers.google.com/drive/api/v3/about-sdk and https://developers.google.com/identity/protocols/OAuth2, so I did this:

  • created a new Google API project and enabled the Drive API
  • Obtain OAuth 2.0 credentials from the Google API Console ( according to https://github.com/googleapis/google-auth-library-nodejs#oauth2-with-installed-apps-electron , I chose 'iOS' option application type when creating the credentials)
  • generated authentican URL (using the client-id and the needed scopes), using 'google-auth-library'
  • created a separate brower window for the sign-in and settings some useful event listeners. Setting the window url to the generated auth url.
  • obtained the token
  • trying to use the token to access the Drive API (not working)
import { google } from 'googleapis';
import { OAuth2Client } from 'google-auth-library';

async function googleSignIn() {
  const oAuth2Client = new OAuth2Client({
    clientId:
      'xxxxxxyyyyzzzz.apps.googleusercontent.com',
    redirectUri: 'com.xxx.yyyyyyy:/oauth2Callback'
  });

  const code = await signInWithPopup(oAuth2Client);

  await oAuth2Client.getToken(code, (err, token) => {
    if (err) {
      return console.error('Error retrieving access token', err);
    }
    oAuth2Client.setCredentials(token);
    listSomeFiles(oAuth2Client);
  });
}

function signInWithPopup(oAuth2Client: OAuth2Client) {
  return new Promise((resolve, reject) => {
    const authWindow = new BrowserWindow({
      width: 500,
      height: 600,
      show: true
    });

    const SCOPES = [
      'https://www.googleapis.com/auth/drive.file',
      'https://www.googleapis.com/auth/drive.appfolder',
      'https://www.googleapis.com/auth/drive.metadata.readonly'
    ];
    const authUrl = oAuth2Client.generateAuthUrl({
      access_type: 'offline',
      scope: SCOPES
    });

    function handleNavigation(url) {
      const { query } = parse(url, true);
      if (query) {
        if (query.error) {
          reject(new Error(`There was an error: ${query.error}`));
        } else if (query.code) {
          // Login is complete
          authWindow.removeAllListeners('closed');
          setImmediate(() => authWindow.close());

          resolve(query.code);
        }
      }
    }

    authWindow.on('closed', () => {
      throw new Error('Auth window was closed by user');
    });

    authWindow.webContents.on('will-navigate', (event, url) => {
      handleNavigation(url);
    });

    authWindow.webContents.on(
      'did-get-redirect-request',
      (event, oldUrl, newUrl) => {
        handleNavigation(newUrl);
      }
    );

    authWindow.loadURL(authUrl);
  });
}

async function listSomeFiles(oAuth2Client: OAuth2Client) {
  const drive = google.drive({ version: 'v3', oAuth2Client });

// the following lines throws the error
// code snippet from https://developers.google.com/drive/api/v3/quickstart/nodejs

  drive.files.list(
    {
      pageSize: 10,
      fields: 'nextPageToken, files(id, name)'
    },
    (err, res) => {
      if (err) return console.log(`The API returned an error: ${err}`);
      const { files } = res.data;
      if (files.length) {
        console.log('Files:');
        files.map(file => {
          console.log(`${file.name} (${file.id})`);
        });
      } else {
        console.log('No files found.');
      }
    }
  );
}

1
Did you check this already? stackoverflow.com/questions/19335503/… - briosheje
Yes. The Drive API seems to be enabled, I can even call the api in the APIs Explorer. - ovidiu-miu
It means that your not sending an access token with your request your user isnt logged in properly. - DaImTo

1 Answers

0
votes

Found the reason, I was missing a parameter in my api request, the 'oauth_token'. I was expecting this to work out of the box, since I've passed the oAuth2Client object (which had the token info) to the google.drive() function.

  drive.files.list(
    {
      pageSize: 10,
      fields: 'nextPageToken, files(id, name)',
      oauth_token: oAuth2Client.credentials.access_token
    },
    (err, res) => {

    }
  );