title: Accessing Google Drive from a Firefox extension
body: <p>I'm trying to access (CRUD) Google Drive from a Firefox extension. Extensions are coded in Javascript, but neither of the two existing javascript SDKs seem to fit; the client-side SDK expects "window" to be available, which isn't the case in extensions, and the server-side SDK seems to rely on Node-specific facilities, as a script that works in node no longer does when I load it in chrome after running it through browserify. Am I stuck using raw REST calls?﻿ The Node script that works looks like this:</p>
  
  <pre><code>var google = require('googleapis');
  var readlineSync = require('readline-sync');
  
  var CLIENT_ID = '....',
      CLIENT_SECRET = '....',
      REDIRECT_URL = 'urn:ietf:wg:oauth:2.0:oob',
      SCOPE = 'https://www.googleapis.com/auth/drive.file';
  
  var oauth2Client = new google.auth.OAuth2(CLIENT_ID, CLIENT_SECRET, REDIRECT_URL);
  
  var url = oauth2Client.generateAuthUrl({
    access_type: 'offline', // 'online' (default) or 'offline' (gets refresh_token)
    scope: SCOPE // If you only need one scope you can pass it as string
  });
  
  var code = readlineSync.question('Auth code? :');
  
  oauth2Client.getToken(code, function(err, tokens) {
    console.log('authenticated?');
    // Now tokens contains an access_token and an optional refresh_token. Save them.
    if(!err) {
      console.log('authenticated');
      oauth2Client.setCredentials(tokens);
    } else {
      console.log('not authenticated');
    }
  });
  </code></pre>
  
  <p>I wrap the node GDrive SDK using browserify on this script:</p>
  
  <pre><code>var Google = new function(){
      this.api = require('googleapis');
      this.clientID = '....';
      this.clientSecret = '....';
      this.redirectURL = 'urn:ietf:wg:oauth:2.0:oob';
      this.scope = 'https://www.googleapis.com/auth/drive.file';
      this.client = new this.api.auth.OAuth2(this.clientID, this.clientSecret, this.redirectURL);
    }
  }
  </code></pre>
  
  <p>which is then called using after clicking a button (if the text field has no code it launches the browser to get one):</p>
  
  <pre><code>function authorize() {
    var code = document.getElementById("code").value.trim();
  
    if (code === '') {
      var url = Google.client.generateAuthUrl({access_type: 'offline', scope: Google.scope});
      var win = Components.classes['@mozilla.org/appshell/window-mediator;1'].getService(Components.interfaces.nsIWindowMediator).getMostRecentWindow('navigator:browser');
      win.gBrowser.selectedTab = win.gBrowser.addTab(url);
    } else {
      Google.client.getToken(code, function(err, tokens) {
        if(!err) {
          Google.client.setCredentials(tokens);
          // store token
          alert('Succesfully authorized');
        } else {
          alert('Not authorized: ' + err); // always ends here
        }
      });
    }
  }
  </code></pre>
  
  <p>But this yields the error <code>Not authorized: Invalid protocol: https:</code></p>