• About Morris Development
  • A Focus for Cloud Efficiency
    • Microsoft Azure
    • Amazon Web Services
  • What our Clients Say
  • Our Products
    • PreschoolDB
    • WebinarDB
  • Contact Us

Morris Development

Custom System Development and Integration

October 1, 2018

Using Google Drive: Server to Server

The vast majority of documentation about Google Drive revolves around the use of OAuth to do client->gdrive directly, bypassing your own server. In our case, we need to be very specific about where documents are placed, how directories are named and what files are acceptable. As such, it is impossible to securely do so on a client application. We must pass the documents “through” our server.

Currently, we do this with Amazon quite a bit. It’s a seamless process and users have no idea where our storage is. However, in that situation, it is simply because we choose to store all files on Amazon S3 as a structural design. In this case, our clients utilize Google Apps for their email and Google Drive for corporate shared drives. So their applications will be saving documents produced on their external staff’s mobile applications directly onto the google drive where the office staff will have access to them on google drive.

While this can be done in a variety of ways, it is far easier to use a “Service Account” (Google Service Accounts) that will make a new account for the company BUT it is not “actually” part of the company. (A company admin will not see it among the users)

Once you get the service account, you’ll get a JSON file with a private key and the email. Save that file!.

Let’s get to the good part! The first step is to get authorized with Google.

using Google.Apis.Drive.v3;
        public static GoogleCredential GetSAC()
        {
            // the location of the security file from google api development service account
            string credentialsFile = "that-json-file-you-got-from-google.json";
            string path = HttpContext.Current.Server.MapPath("~/App_Data");
            string keyFilePath = path + "/" + credentialsFile;
            // load the file into a stream so we can send it to google
            var stream = new FileStream(keyFilePath, FileMode.Open, FileAccess.Read);
            //  prepare a credential from google  (not approved yet, just set up)
            var credential = GoogleCredential.FromStream(stream);
            //define exactly what kind of authority we want from google
            string[] scopes = new string[] { DriveService.Scope.Drive }; // Full access
            //send that request along with our security account in the credential.               
            credential = credential.CreateScoped(scopes);
            // at this point, we have a credential object that we'll send to create our Drive Service
            return credential;
        }

Now, I popped the JSON file into the App_Data directory, but you can put it anywhere on the server. I’d SERIOUSLY recommend that you don’t keep yours there, but rather someplace more secure so you can actually put your code under version control.

So this little script loads that credentials file as a stream, the scope of permissions we want into this credentials object. Now we need to create the service. That’s where we send the credentials to Google, and ask for access to a set of APIs. The plugin will handle the addresses, etc. but you “could” just code it all using HTTP calls. In the background, all it’s doing is getting a bearer token that will be going in the header of the requests.

Anyway, here’s how we create the service that we will use to execute all the Google Drive Commands:

/* We create a service object and include our app name and the credentials we just put together 
  (we could also initialize other services in the same way if we chose)    */   
        public static DriveService GetService()
        {
            // Login to google
            GoogleCredential credential = GetSAC();
            // Create Google Drive service API and attach our credential to it.
            // note: your ApplicationName can actually be whatever you want.  I don't think it makes a difference
            DriveService service = new DriveService(new BaseClientService.Initializer()
            {
                HttpClientInitializer = credential,
                ApplicationName = "yourApplicationName",  
            });
            return service;
        }

Okay, now we’ve got the service object. At this point, we really have done nothing but get together our credentials and an object that has a list of command functions built into it. Google hasn’t been contacted at all. So, let’s do that!

The first step is going to be über-simple. We’ll just get a directory list. If you just made the account, then it should have nothing there but the “Welcome to Google Drive!” file.

So, here’s the function that will get these files. You’ll notice I added a couple parameters: query and service.

Quite often you’ll be doing several things at once. For example, if you want to make a folder, it’s best to check to see if that folder exists already (same with files). Google is VERY different than Amazon’s S3. S3 uses the actual path as a key, but Google uses more of a relational database structure, where a file has an array of parent folders.

 ///Get list of all files on the Google Drive.
        public static List GetGoogleFiles(string query = "", DriveService service=null)
        {
            // retreive an active service with google's token of authority if one doesn't already exist
            if (service == null)
                service = GetService();
            // define parameters of request.
            FilesResource.ListRequest FileListRequest = service.Files.List();
            // search examples:
            /*
            https://developers.google.com/drive/api/v3/search-parameters
            modifiedTime > '2012-06-04T12:00:00' and (mimeType contains 'image/' or mimeType contains 'video/')
            mimeType = 'application/vnd.google-apps.folder'
           for example:   name contains 'hello' and name contains 'goodbye'
            */
            //listRequest.PageSize = 10;
            //listRequest.PageToken = 10;
            FileListRequest.Fields = "nextPageToken, files(id, name, size, version, createdTime, parents)";
            FileListRequest.Q = query;
            //get file list.
            IList files = FileListRequest.Execute().Files;
            List FileList = new List();
            if (files != null && files.Count > 0)
            {
                foreach (var file in files)
                {
                    GoogleDriveFile File = new GoogleDriveFile
                    {
                        ID = file.Id,
                        Name = file.Name,
                        Size = file.Size,
                        Version = file.Version,
                        CreatedDate = file.CreatedTime,
                        Parents = file.Parents
                    };
                    FileList.Add(File);
                }
            }
            return FileList;
        }

I left some examples of parameters in there, since it isn’t nearly as intuitive as you’d think, and getting the structure wrong results in a nasty error rather than no results.

There’s a bit more information about parameters here: Google’s single page about parameters, but you’ll be better off doing it by trial and error. I was pretty disappointed with their documentation (hence this entire post).

So, here’s how this will work in your API controller:

   public IHttpActionResult Get()
        {
            List g = GoogleDriveModule.GetGoogleFiles();
            return Ok(g);
        }

That should give you all the files. Not just in that directory either…. ALL of them. So, you’ll want to get them filtered down a bit before things get out of hand.

One thing you need to know is that “directories” are just files. So, you’ll make a new directory, and it gives you an ID. Each file has a “Parents” property that contains a string array of these IDs.

The next post will have some examples of uploads, deleting, downloading, making directories, updating files, etc… For now, this should get you going.

Article by MacGyver / ASP.net, C#, Google, Web Developer

About MacGyver

I've worked with database systems for over 20 years, and started my own company in 2000. Almost all my business consists of internal database systems, either ERP or CRM. My programming is primarily in Angular / Microsoft C# and MS SQL.

About This Site

Morris Development has been specializing in internal database system design and integration since 1999. We provide long-term management and support of secure data systems for many businesses as well as developing the more complex code structures for ERP systems like Intellievent, Apidas, and AVMS.

This site is primarily for our developers to keep track up various technologies and updates that are used by Morris Development.

Training

Integrating Angular Microsite with .Net

Private Data Caching with Google Storage

Continuous Deployment for Production Releases?

Azure Websites – the perfect Angular host

Angular 2

  • Angular 2 Authentication
  • Angular Command Line Interface
  • Material Design for Angular
  • Using Observables in Angular 2

Mentors

  • Ben Nadel
  • Dan Wahlin
  • Deborah Kurata
  • John Papa

Staff

  • Dan Morris

Training

  • Google Development Courses
  • Microsoft Virtual Academy
  • PluralSight
  • Test Deep Links

© 2025 · Morris Development