## Setting Up The Demo 1. Follow the directions for setting up [Google Auth With Firebase][firebase-google-setup]. 2. Look at the directions for setting up [Google Drive Auth][google-drive-setup]. You will already have completed most of this in step 1, but you need to perform the extra step of *enabling the Drive API*, here is the relevant part of that page (I've bolded the important parts): > 1. Go to the [Google Developers Console][google-developer-console]. > 2. **Select a project**, or create a new one. > 3. In the sidebar on the left, expand APIs & auth. Next, click APIs. Select the Enabled APIs link in the API section to see a list of all your enabled APIs. **Make sure that the Drive API is on the list of enabled APIs**. If you have not enabled it, select the API from the list of APIs, then **select the Enable API button** for the API. 3. Since you are likely hosting it locally for this demo, make sure `localhost` is still an approved origin in both your firebase settings, and the google developer console. 4. Now you should be able to open `index.html` (above). Make sure to edit the `` portion to accurately reflect your applications name. 5. If you have done everything correctly, you should be get an authorization popup immediately, and once approved, you should see a list of your files logged to the console. ## How it Works The Firebase `authWithOAuthPopup` and `authWithOAuthRedirect` do return OAuth tokens which are usable for performing API calls to Google (I have successfully done the same thing with GitHub as well). However, to access a users Google Drive contents, we must request an additional `scope` from Google. Fortunately, Firebase provides a way [to do just that][firebase-google-setup]: > authWithOAuthPopup() and authWithOAuthRedirect() take an optional third parameter which is an object containing any of the following settings > - **remember** : *... redacted because it's not important to the scope of this gist* > - **scope** : `string` - A comma-delimited list of requested extended permissions. See [Google's documentation][google-scopes] for more information The link in the Firebase docs lists a few of the available scopes, but any Google OAuth scope *should* work. We can find the scope we need in the relevant Google Drive [documentation][drive-scopes]. `https://www.googleapis.com/auth/drive.metadata.readonly` allows us to read file metadata, but not see file contents or edit anything. That seems like a nice, demo friendly authorization level, so let's just use that. You will need to pick whatever is appropriate for your application. I have also added the `email` scope, which allows us to see their google email address. Once we have all that figured out we create a new Firebase `ref`, and trigger authorization via the Firebase API. ```js var ref = new Firebase("https://.firebaseio.com/"); ref.authWithOAuthPopup( "google", handleFirebaseAuthData, {scope: "email, https://www.googleapis.com/auth/drive"} ); ``` Upon successful authentication, Firebase returns an `authData` object to our callback. That object contains a token that can be used to authenticate calls to whatever Google API's we have been granted access to (as determined by the `scope` we requested above). In this case, the relevant token is a `string`, and found at `authData.google.accessToken`. Now, we *could* start making requests to the [Google Drive Rest API][drive-rest-api], manually setting the `Authorization` header as [describe here][cors-header]. But, Google already provides a nice javascript API for drive, so let's load it up and pass in the authentication token we get back from Firebase: ```js gapi.client.load('drive', 'v2', handleDriveLoaded); // load the google drive api function handleDriveLoaded() { var ref = new Firebase(FIREBASE_URL); ref.authWithOAuthPopup( "google", handleFirebaseAuthData, {scope: GOOGLE_OATH_SCOPES} ); } function handleAuthData(error, authData) { if (error) { /* do error handling */ } gapi.auth.setToken({ access_token: authData.google.accessToken }); gapi.client.drive.files.list().execute(handleFileList); } ``` Notice the call to [`gapi.auth.setToken`][set-token], there is a bit of weirdness there. We need to reformat the token so it fits [the format the Google API is expecting][google-auth2-token-object]. Basically, we just change the property name for the token string from `accessToken` to `access_token`. The example code takes things a step further by fetching all your files and adding them to the DOM as clickable links. That code is pretty straightforward and outside the scope of this Gist. I leave it to the reader to explore further. If this gist helped you please feel free to pass it on. If you write a blog or StackOverflow answer based on it's content, I would appreciate attribution (see copyright notice and license below). [firebase-google-setup]:https://www.firebase.com/docs/web/guide/login/google.html [google-drive-setup]:https://developers.google.com/drive/web/auth/web-client [google-auth2-token-object]:https://developers.google.com/api-client-library/javascript/reference/referencedocs#OAuth20TokenObject [google-developer-console]:https://console.developers.google.com/ [set-token]:https://developers.google.com/api-client-library/javascript/reference/referencedocs#--------gapiauthsettokentoken------ [google-scopes]:https://developers.google.com/+/api/oauth#scopes [drive-scopes]:https://developers.google.com/drive/web/scopes [cors-header]:https://developers.google.com/api-client-library/javascript/features/cors#--------example-1-using-the-request-header------ [drive-rest-api]:https://developers.google.com/drive/v2/reference/files/list