Using Google Drive REST API with Laravel

In this tutorial, we’ll be using Google Drive REST API with Laravel application. We’ll authenticate the user with OAuth service and retrieve their access token. We’ll then use it to manage their drive data and perform read and write operations on their behalf. 

Create a new project and generate authentication scaffolding. Install Socialite and Google Client Library. We’ll use Socialite to authenticate the user with Google’s OAuth service.

Create Google Drive Application

Now head over to Google Developers Console and create or select an existing project. You can use this wizard to register Google Drive Application.

Now click continue and go to credentials.

Choose Google drive API, select Web Server and check User Data. 

Enter client ID name and enter Javascript origin and redirect URIs. Enter your domain name instead of localhost address for production. Redirect URI will be used to redirect users back to your app after authentication. Create client ID and enter product name. Download JSON credentials file and save it.

 

Now click on Enable API and Services from the dashboard.

Search for Google Drive and Google+ APIs and make sure both are enabled.

Configure Google Service

Now edit config/serivces.php  and add google service at the end of services array.

Now define enviroment variables in .env file.

You Redirect URI must match with the one we entered during application setup.

OAuth Authentication

Add these routes to your app/routes/web.php  file.

Now define both methods in LoginController.

We’re using “https://www.googleapis.com/auth/drive” scope to request user permissions for managing their drive data in redirectToGoogleProvider() method. In handleProviderGoogleCallback()  method, we’re creating a new user if it doesn’t exist. if it exists, we’re updating their refresh_token. Make sure you add this column to your user’s table by modifying user migration and setting the password to nullable.

Dependency Injection

Create GoogleServiceProvider. We’ll inject Google Client class into service container to avoid unnecessary instantiation.

After instantiation of Google_Client  class, we’re reading google service credentials and creating a temporary file with it. We’re doing this because setAuthConfig() method expects json file with credentials that we downloaded after setting up drive app. Now every time we type hint Google_Client in our methods, we’ll have access to this instance from service container.

Routes and Controller

Add these routes to your app. Create DriveController and implement these methods to handle requests.

In our controller’s constructor, we can’t access Auth user, this is why we’re using a closure based middleware. We’re setting refresh token and creating a new instance of  Google_Service_Drive  with Google_Client  instance from service container.

Retrieving Folders

In getDrive()  method, we’re calling ListFolders($id)  method with ‘root’ param. root refers to the main directory of google drive. Then we’re retrieving root folders with  files->listFiles($optParams) method. If you want to access files in a specific folder you can pass folder ID instead of root to access its files. You can also recursively calling ListFolder() method in foreach loop.

Creating Files from Storage and Form Uploads

createFile($file, $parent_id = null) takes two arguments. First one is a file. It can be a file object retrieved from requests or a storage path. You can pass parent id as the second param. If you want to create a new file under a specific folder. After creating file, it returns file id.

Creating Folders

You can pass folder name to  createFolder($folder_name) method to create a new folder and get its ID.

Deleting Folders

To delete a folder or file, all you have to do is to pass an id to deleteFileOrFolder($id) and it will be deleted from the drive.

I’ve set up an example project repository. If you’ve any issue integrating Google Drive API in your app, comment your issue and i’ll try to help you with it.

Share this post

26 thoughts on “Using Google Drive REST API with Laravel”

  1. Nice. Useful tutorial.
    Could you please make a tutorial on a Timesheet app. Users/Employees would enter their daily work: start time, end time, project name, notes and any expenses.
    Many Thanks !

  2. I have an error when i´m trying to upload a file, the app says “Trying to get property of non-object” What is the problem with the code?

    1. Are you uploading the file through a web form? Make sure you have enctype="multipart/form-data" on your form. Also make sure $request->file('file') exists before passing it to createFile($request->file('file')) method.

  3. i made all the things that are in this document and it’s write me:
    Too few arguments to function App\Http\Controllers\DriveController::__construct(), 0 passed in /opt/lampp/htdocs/Agile/app/Http/Controllers/DashbourdController.php on line 11 and exactly 1 expected
    what should i do?

    1. Have you created GoogleClientProvider? Can you share DriveController.php, GoogleClientProvider.php and DashboardController.php code in a Gist so that I can look into the issue?

  4. i have a problem that Auth::user() is null and then the DriveController is crashing in the cunstructor.
    What is the problem?

    Thanks

  5. Hi, I get the following error when I try to log in for the first time, it seems that the application does not get the value of refresh_token

    Integrity constraint violation: 1048 Column ‘refresh_token’ cannot be null (SQL: insert into users (email, refresh_token, name, updated_at, created_at) values (xxx@xxxx, , xxxxxx, 2018-08-14 20:13:44, 2018-08-14 20:13:44))

    Can you help me?

    1. Try dumping $auth_user in handleProviderGoogleCallback method on LoginController to see if it has refresh_token property on redirect after you authorize access to OAuth service.

      1. Don’t sign up using Laravel default auth form. After setting up app and running migrations, redirect to /login/google and it will redirect to Google OAuth page where you’ll be asked to allow access to your account. After allowing, you’ll be redirect back to Laravel app with a refresh_token and a new user will be created with your google account email.

    1. Just change $table->string('refresh_token') to $table->string('refresh_token')->nullable(); in users table migration. After installing composer dependencies, run migrations. Now redirect to /login/google/ route in browser. It will redirect you to Google and ask your to allow access to your account. After allowing, you’ll be redirected back to your Laravel app and a new user will be created with your Google email.

      1. i’m getting this error: Class ‘App\Http\Controllers\Auth\Socialite’ not found. i install the socialite and add use to the logonController.
        what do i need to do?

  6. Hi,
    Once I get through the authentication process, how do I create a new $client instance with my credentials to insert into the DriveController($client)

    1. It’s already being done in DriveController. You can access Google_Service_Drive instance with $this->drive. We’ve GoogleClientProvider which binds Google_Client into Laravel service container and automatically resolves it when you type hint on your controller methods and constructors. We’ve an instance of Google_Client in DriveController constructor.

  7. hi,
    I got error when trying to access /drive :
    “Class App\Http\Controllers\Google_Client does not exist”
    Thank you for your attention.

  8. I’ ve used dd($auth_user->refreshToken); because when I want to upload a file or maybe see my files, I have an error called “Trying to get property of non-object”

    And dd(—) returns to me “null”

    So, what can I do? Please and thank you very much!

  9. Hi,
    I’m a little new here if I follow this tutorial and then run: php artisan serve –port=8080 and then go to
    localhost::8080/drive is that supposed to work?

    1. Yes. Make sure you also change Redirect URI in .env file to GOOGLE_REDIRECT=’http://127.0.0.1:8080/login/google/callback’ and also add this to authorized redirect URIs when creating your app in Google developers console.

      1. I think there is something missing here like how do I create a new user in the database? because when I register in the home page it creates a user without a refresh token and login/google redirects me back to the home page

        1. It’s already being done in LoginController‘s handleProviderGoogleCallback method. In redirectToGoogleProvider method, user will be redirected to Google’s OAuth service and redirected back with a refresh_token. A new user will created with a refresh_token if it doesn’t exist. refresh_token will be updated for existing users.

          1. Could you explain more about the refresh_token? I only see answers that don’t help. I’ve been trying to fix the error for 4 days but I still get “Refresh token must be passed in or set as part of setAccessToken”… And if I return the refresh_token, this is null.

            Could you please explain more without saying that the refresh_token will be generated automatically (which does not happen)?

          2. Automatically? where did i say that? I’m afraid you don’t understand OAuth workflow. We’ve these two routes in our app.

            // Redirects you to Google OAuth
            Route::get('/login/google', 'Auth\LoginController@redirectToGoogleProvider');

            // Handles redirect callback after user authorize access to their account.
            Route::get('login/google/callback', 'Auth\LoginController@handleProviderGoogleCallback');

            In handleProviderGoogleCallback methods, Socialite retrieves user account information along with refresh_token. If a user with email already exists, we’ll simply refresh their token, otherwise we’ll create a new user with that email and token.
            User::firstOrCreate(['email' => $auth_user->email], ['refresh_token' => $auth_user->refreshToken, 'name' => $auth_user->name]);

  10. I’m sorry bro! Honestly, it doesn’t work for me. I have done the tutorial 4 times but I cann’t solve the problem with refresh_token. Sorry, before I said “Automatically” and it’s not true. But you say that the Refresh_token will be updated. But I don’t know how to do that. I have the same data as you but my app does not work.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.