I'm using Google Sheet Api on PHP framework and facing error while updating sheet.
Fatal error: Uncaught Google_Service_Exception: {
"error": {
"code": 403,
"message": "Request had insufficient authentication scopes.",
"errors": [
{
"message": "Request had insufficient authentication scopes.",
"domain": "global",
"reason": "forbidden"
}
],
"status": "PERMISSION_DENIED"
}
How can I fix it?
function add($spreadsheetId, $range, $value, $service){
$result = $service->spreadsheets_values->get($spreadsheetId, $range);
$numRows = $result->getValues() != null ? count($result->getValues()) : 0;
printf("%d rows retrieved.", $numRows);
$body = new Google_Service_Sheets_ValueRange([
'values' => [$value]
]);
$end = chr(65 + count($value) - 1);
$range = $range."!A".($numRows + 1).":".$end;//ex:Sheet!A6:H
printf("%s\n", $range);
$result = $service->spreadsheets_values->update($spreadsheetId, $range, $body, ['valueInputOption' => 'USER_ENTERED']);
printf("%d cells added.\n", $result->getUpdatedCells());
}
I also had error like that.
And I solved it by downloading credential.json file again.
Additionally, Please check if spreadsheetId is correct or wrote $client->setScopes(Google_Service_Sheets::SPREADSHEETS); before creating service.
Related
I got a PHP BigQueryClient that I use to export big tables to csv from BQ, but after running for a while they throw and error with code 401:
Google\Cloud\Core\Exception\ServiceException
{
"error": {
"code": 401,
"message": "Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
"errors": [
{
"message": "Invalid Credentials",
"domain": "global",
"reason": "authError",
"location": "Authorization",
"locationType": "header"
}
],
"status": "UNAUTHENTICATED"
}
}
it occurs when running a long while that goes over the rows of the table like this
$bigQuery = new BigQueryClient([
'keyFile' => $array[$key],
'projectId' => $this->projectId
]);
//This is to get total row count so we can loop over it
$info = $bigQuery->dataset($this->datasetId)->table($tableName)->info();
//Output row count, and status message
$this->info($this->messagePrepend . "Rows: " . number_format($info['numRows']) . ", Chunk size: " . number_format($this->chunkSize) . " – Processing.." . PHP_EOL);
$startTime = Carbon::now();
//Open our output file
$file = fopen(storage_path("tmp/{$tableName}.csv"), 'w');
fputcsv($file, $this->tableHeaders);
$orderBy = match ($keyword) {
default => "id"
};
while ($info['numRows'] > $offset) {
$config = $bigQuery->query("SELECT * FROM {$this->datasetId}.{$tableName} ORDER BY {$orderBy} ASC LIMIT {$this->chunkSize} OFFSET {$offset}");
$job = $bigQuery->startQuery($config);
$queryResults = collect($job->queryResults());
$queryResults->map(function ($row) {
$line = [FORM LINE]
fputcsv($file, $line);
});
$offset += $this->chunkSize;
}
I've tried looking for the causes for this, and it seems like the issue is that the client token expires after an hour.
Despite that I've not found a way to refresh it, cause it doesn't seem to do so automatically, could anyone help me figure out how to do that?
I've read cloud bigquery docs but they didn't provide me with much answers, and neither did google
Resolved it by updating the instance of BigQueryClient when an exception is thrown:
try {
$job = $bigQuery->startQuery($config);
} catch (\Throwable $th) {
$this->warn("Code: " . $th->getCode() . ": " . $th->getMessage(), 'vvv');
$bigQuery = new BigQueryClient([
'keyFile' => $array[$key],
'projectId' => $this->projectId
]);
$job = $bigQuery->startQuery($config);
}
I found the same problem with the solution for the same error in javascript but couldn't make it work for PHP so please help
ERROR: 542{ "error": { "code": 400, "message": "'valueInputOption' is required but not specified", "errors": [ { "message": "'valueInputOption' is required but not specified", "domain": "global", "reason": "badRequest" } ], "status": "INVALID_ARGUMENT" } }
this is the error i get when i use the following code:
<?php
$time = time();
$name = $_GET['cname'];
$invoiceNumber = $_GET['invoice'];
$date = $_GET['date'];
$percentage = $_GET['percentage'];
$taxableValue = $_GET['taxableValue'];
$discount = $_GET['discount'];
$invoictotoal = $_GET['total'];
$sgst = $percentage*$taxableValue/100;
echo $discount;
require __DIR__ . '/vendor/autoload.php';
/**
* Returns an authorized API client.
* #return Client the authorized client object
*/
function getClient()
{
$client = new \Google_Client();
$client->setApplicationName('Google Sheets API PHP Quickstart');
$client->setScopes([\Google_Service_Sheets::SPREADSHEETS]);
$client->setAuthConfig('C:\Users\mitta\Desktop\Seagull\form\credentials.json');
$client->setAccessType('offline');
return $client;
}
// Get the API client and construct the service object.
$client = getClient();
$client->addScope(Google\Service\Drive::DRIVE);
$client->setScopes(['https://www.googleapis.com/auth/spreadsheets']);
$service = new Google\Service\Sheets($client);
// Prints the names and majors of students in a sample spreadsheet:
// https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit
try{
$spreadsheetId = '1H6EHEHGsHyRZTE-j8er9DrZjj-b9TkRg0p96K-h90Pc';
$range = 'Form Responses 1';
$valuetoinsert = [
[$time,$name,$invoiceNumber,$date,$percentage,$invoictotoal,$taxableValue,$discount,$sgst,$sgst],
];
$body = new Google_Service_Sheets_ValueRange([
'values' => $valuetoinsert
]);
$params = [
'valueInputOption' => 'RAW'
];
$inset = [
"insertDataOption" => "INSERT_ROWS"
];
$result = $service->spreadsheets_values->append(
$spreadsheetId,
$range,
$body
);
}
catch(Exception $e) {
// TODO(developer) - handle error appropriately
echo $e->getMessage();
}
?>
so i added the valuInputOption parameter but then i get different error
error: Uncaught TypeError: implode(): Argument #2 ($array) must be of type ?array, string given in D:\xamp\htdocs\form\vendor\google\apiclient\src\Google\Service\Resource.php:291 Stack trace: #0 D:\xamp\htdocs\form\vendor\google\apiclient\src\Google\Service\Resource.php(291): implode(Array, '&') #1 D:\xamp\htdocs\form\vendor\google\apiclient\src\Google\Service\Resource.php(190): Google_Service_Resource->createRequestUri('v4/spreadsheets...', Array) #2 D:\xamp\htdocs\form\vendor\google\apiclient-services\src\Sheets\Resource\SpreadsheetsValues.php(83): Google_Service_Resource->call('append', Array, 'Google\Service\...') #3 D:\xamp\htdocs\form\insert.php(54): Google\Service\Sheets\Resource\SpreadsheetsValues->append('1H6EHEHGsHyRZTE...', 'Form Responses ...', Object(Google\Service\Sheets\ValueRange), Array, Array) #4 {main} thrown in D:\xamp\htdocs\form\vendor\google\apiclient\src\Google\Service\Resource.php on line 291
The code used for this error is the sam and i added 2 more parameters:
$result = $service->spreadsheets_values->append(
$spreadsheetId,
$range,
$body,
$inset,
$params
);
I have a sheet that needs to be updated with some data.
Code that should add «hello» and «bye» to my sheet:
require __DIR__ . '/vendor/autoload.php';
function getClient()
{
...
}
$client = getClient();
$service = new Google_Service_Sheets($client);
$spreadsheetId = 'ID';
$range = 'A1';
$value = [
["hello", "bye"]
];
$body = new Google_Service_Sheets_ValueRange(
["majorDimension" => "ROWS"],
["values" => $value]
);
$params = array('valueInputOption' => 'USER_ENTERED');
$requestBody = new Google_Service_Sheets_ValueRange();
$result = $service->spreadsheets_values->update($spreadsheetId, $range,
$body, $params);
printf("%d cells updated.", $result->getUpdatedCells());
result:
0 cells updated.
I also tried to change $range = 'A1’; to something like Sheet1!A1 or A1-B2 and variety of another ranges; but in that case I receive error:
{ "error":
{ "code": 400, "message": "Unable to parse range: A1-B2",
"errors":
[
{ "message": "Unable to parse range: A1-B2",
"domain": "global",
"reason": "badRequest" } ],
"status": "INVALID_ARGUMENT" } }
How about this modification?
Answer 1:
0 cells updated.
About the reason of above issue, if you want to use "majorDimension" => "ROWS", please modify as follows.
From:
$body = new Google_Service_Sheets_ValueRange(
["majorDimension" => "ROWS"],
["values" => $value]
);
To:
$body = new Google_Service_Sheets_ValueRange([
"majorDimension" => "ROWS",
"values" => $value
]);
In your case, I think that the following modification can be also used.
$body = new Google_Service_Sheets_ValueRange([
"values" => $value
]);
Answer 2:
also tried to change $range = 'A1’; to something like Sheet1!A1 or A1-B2 and variety of another ranges; but in that case I receive error:
About the reason of above issue, if you want to use the range, how about the following modification?
From:
$range = 'A1';
To:
$range = 'Sheet1!A1';
and
$range = 'Sheet1!A1:B1';
References:
Method: spreadsheets.values.update
A1 notation
This is my code for gmail watch request push notification
define('SCOPES', implode(' ', array(
Google_Service_Gmail::MAIL_GOOGLE_COM)
));
$this->client = new Google_Client();
$this->client->setApplicationName(APPLICATION_NAME);
$this->client->setScopes(SCOPES);
$this->client->setAuthConfig(CLIENT_SECRET_PATH);
$this->client->setAccessType('offline');
$this->client->setApprovalPrompt('force');
$credentialsPath = CREDENTIALS_PATH;
if(!file_exists($credentialsPath)){
redirect('gmail');
}
$accessToken = json_decode(file_get_contents($credentialsPath), true);
$this->token = $accessToken['access_token'];
$this->client->setAccessToken($accessToken);
if ($this->client->isAccessTokenExpired()) {
$refreshTokenSaved = $this->client->getRefreshToken();
$this->client->fetchAccessTokenWithRefreshToken($refreshTokenSaved);
//$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
file_put_contents($credentialsPath, json_encode($this->client->getAccessToken()));
}
$service = new Google_Service_Gmail($this->client);
$watchreq = new Google_Service_Gmail_WatchRequest();
$watchreq->setLabelIds(array('INBOX'));
$watchreq->setTopicName('projects/composed-field-201410/topics/wooglobe');
$msg = $service->users->watch('me', $watchreq);
i am getting this error
Type: Google_Service_Exception
Message: { "error": { "errors": [ { "domain": "global", "reason": "backendError", "message": "Backend Error" } ], "code": 500, "message": "Backend Error" } }
Filename: D:\xampp\htdocs\viralgreats\admin\vendor\google\apiclient\src\Google\Http\REST.php
Line Number: 118
i have a Problem with the Spreadsheed api and the "scopes".
With these script i want to update Cells on a Sheet.
I do not work with composer ich have just download the package in intereating it. The Token is already there and the error is from these row:
"$response = $service->spreadsheets_values->get($spreadsheetId, $range);"
<?php
session_start();
require_once __DIR__.'/vendor/autoload.php';
$client = new Google_Client();
$client->setAuthConfig('oauth-credentials.json');
$client->addScope(Google_Service_Drive::DRIVE_METADATA_READONLY);
if (isset($_SESSION['access_token']) && $_SESSION['access_token'])
{
$client->setAccessToken($_SESSION['access_token']);
echo "<pre>";
$service = new Google_Service_Sheets($client);
$spreadsheetId = 'xxx';
$range = 'Tabellenblatt1!A2:E';
$response = $service->spreadsheets_values->get($spreadsheetId, $range);
$values = $response->getValues();
if (count($values) == 0) {
print "No data found.\n";
} else {
print "Name, Major:\n";
foreach ($values as $row) {
// Print columns A and E, which correspond to indices 0 and 4.
printf("%s, %s <br>", $row[0], $row[4]);
}
}
} else {
$redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/api/oauth2callback.php';
header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}
?>
These Code brings the following Error
Fatal error: Uncaught exception 'Google_Service_Exception' with message '{
"error": {
"code": 403,
"message": "Request had insufficient authentication scopes.",
"errors": [
{
"message": "Request had insufficient authentication scopes.",
"domain": "global",
"reason": "forbidden"
}
],
"status": "PERMISSION_DENIED"
}
}
You have this scope defined:
$client->addScope(Google_Service_Drive::DRIVE_METADATA_READONLY);
For accessing a spreadsheet value:
$response = $service->spreadsheets_values->get($spreadsheetId, $range);
You should have:
$client->addScope(Google_Service_Sheets::SPREADSHEETS_READONLY);
or
$client->addScope(Google_Service_Sheets::SPREADSHEETS);
Source:
https://developers.google.com/identity/protocols/googlescopes#sheetsv4
You Must Update the scope as #random425 said,
but after that delete the Token.json.
that will start the process of verification again what will give you new token with new scope that you have changed to.