6

I am facing an issue with quickstart php script here: https://developers.google.com/drive/v2/web/quickstart/php

When I run the script first time, it executes perfectly and the access token is stored in a file called: drive-php-quickstart.json

When I run the script second time, it gives me the error:

Error start:

Notice: Undefined index: expires_in in \google-api-php-client\src\Google\Client.php on line 485

Fatal error: Uncaught exception 'LogicException' with message 'refresh token must be passed in or set as part of setAccessToken' in

Error end:

My assumption is that access token been saved in the file is not in the right format.

Current format:

ya29.CODE-oN_Bearer36001/_ANOTHER-CODE-ANOTHER_ANOTHER_CODE

As you can see, it does not contain the variable "expires_in"

Any suggestions where I am going wrong ? I am running the script as it is, with no modifications.

CalmWinds
  • 157
  • 1
  • 3
  • 13
  • What, exactly, are you running on App Engine? The quickstart you point to, and apparently all the text on your question, indicate you're running locally, nothing to do with App Engine. If so, can you please change tags? If not, edit your question to clarify where App Engine gets in? Thanks. – Alex Martelli Dec 20 '15 at 19:07
  • Thank you Alex. I have made the changes. Yes, I am currently executing locally but I would be transferring it to Google App Engine shortly. – CalmWinds Dec 21 '15 at 16:31
  • I've got the exact problem. Running the script with no modifications. First time it runs perfectly fine, second time it bails with `refresh token must be passed in or set as part of setAccessToken`. – Erfan Jan 24 '16 at 13:15

2 Answers2

12

I've debugged it.... The person who wrote it made a mistake by not calling json_encode before writing the auth result to the token.json file.

You can fix it by adding json_encode on line 45.

So...

file_put_contents($credentialsPath, $accessToken);

...should be:

file_put_contents($credentialsPath, json_encode($accessToken));

I've submitted feedback so hopefully it'll be fixed.

edit: same issue happens for the token refresh call in that same method

edit2: Here's my related comment in a Github discussion and an answer from Google: https://github.com/google/google-api-php-client/issues/263#issuecomment-186557360

I suggested something along the following lines:

if ($client->isAccessTokenExpired()) {
    $refreshToken = $client->getRefreshToken();
    $client->refreshToken($refreshToken);
    $newAccessToken = $client->getAccessToken();
    $newAccessToken['refresh_token'] = $refreshToken;
    file_put_contents($credentialsPath, json_encode($newAccessToken));
}

Instead of:

// Refresh the token if it's expired.
if ($client->isAccessTokenExpired()) {
    $client->refreshToken($client->getRefreshToken());
    file_put_contents($credentialsPath, $client->getAccessToken());
}
Erfan
  • 2,959
  • 2
  • 17
  • 21
  • Thank you! I've also submitted feedback. Although it appears to be line 47 – Roshan Bhumbra Apr 09 '16 at 20:48
  • @RoshanBhumbra ah yeah, maybe it's 47.. There's some more information in this Github ticket: https://github.com/google/google-api-php-client/issues/263#issuecomment-186557360 – Erfan Apr 10 '16 at 13:51
  • @Erfan - I had to pretty much apply your refresh_token setting in your github comment. Can you mention that here or paste that snippet here? I feel it'd be useful. – meder omuraliev Aug 24 '16 at 17:42
  • Thanks @mederomuraliev, added :) – Erfan Aug 25 '16 at 02:25
  • Sweet. Actually, I did implement that and it has the `refresh_token` node in the `sheets.googleapis.com-php-quickstart.json` file, but I get `Fatal error: Uncaught exception 'LogicException' with message 'refresh token must be passed in or set as part of setAccessToken'` on subsequent calls. Any idea? – meder omuraliev Aug 25 '16 at 15:33
  • I remember getting that as well, I think it was pretty straightforward to fix, can't remember how though @mederomuraliev – Erfan Aug 29 '16 at 03:28
  • @Erfan I am using sheet API v4.. having same code but it is still giving same error "refresh token must be passed in or set as part of setAccessToken” ?? – Hamza Zafeer Aug 17 '17 at 13:53
0

Google has updated their PHP Quickstart, with an improved method to handle this:

// Exchange authorization code for an access token.
$accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
$client->setAccessToken($accessToken);

// Refresh the token if it's expired.
if ($client->isAccessTokenExpired()) {
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
file_put_contents($credentialsPath, json_encode($client->getAccessToken()));
}
dxdc
  • 435
  • 3
  • 8