Bigquery could not get default credentials - php

I'm trying to setup Google Bigquery with Firebase and am having some issues. I have gcloud installed on my machine (MacOS Sierra) and have google cloud installed via composer on my project.
The following code on my project:
# Includes the autoloader for libraries installed with composer
require __DIR__ . '/vendor/autoload.php';
# Imports the Google Cloud client library
use Google\Cloud\BigQuery\BigQueryClient;
# Your Google Cloud Platform project ID
$projectId = 'hidden here only';
# Instantiates a client
$bigquery = new BigQueryClient([
'projectId' => $projectId
]);
# The name for the new dataset
$datasetName = 'test_dataset';
# Creates the new dataset
$dataset = $bigquery->createDataset($datasetName);
echo 'Dataset ' . $dataset->id() . ' created.';
All I'm trying to do is just create a dataset within bigquery via the library but I'm not able to due to the following error:
Fatal error: Uncaught Google\Cloud\Exception\ServiceException: Could not load the default credentials. Browse to https://developers.google.com/accounts/docs/application-default-credentials for more information in /Applications/MAMP/htdocs/projects/work/bigquery-tests/vendor/google/cloud/src/RequestWrapper.php on line 219
I've tried running gcloud beta auth applications-default login as the example code says to do but after logging in on the browser, the error is still present. Any help would be great, thanks!

You were very close, just you need to setup the service account default credentials see lines with putenv and useApplicationDefaultCredentials(). This is a working code I have using the library https://github.com/google/google-api-php-client You need to obtain your service account key file from the console: https://console.cloud.google.com/iam-admin/serviceaccounts/
composer.json
{
"require": {
"google/cloud": "^0.13.0",
"google/apiclient": "^2.0"
}
}
php file
# Imports the Google Cloud client library
use Google\Cloud\BigQuery\BigQueryClient;
use Google\Cloud\ServiceBuilder;
$query="SELECT repository_url,
repository_has_downloads
FROM [publicdata:samples.github_timeline]
LIMIT 10";
$client = new Google_Client();
putenv('GOOGLE_APPLICATION_CREDENTIALS='.dirname(__FILE__) . '/.ssh/dummyname-7f0004z148e1.json');//this can be created with other ENV mode server side
$client->useApplicationDefaultCredentials();
$builder = new ServiceBuilder([
'projectId' => 'edited',
]);
$bigQuery = $builder->bigQuery();
$job = $bigQuery->runQueryAsJob($query);
$info=$job->info();
// print_r($info);
// exit;
$queryResults = $job->queryResults();
/*$queryResults = $bigQuery->runQuery(
$query,
['useLegacySql' => true]);*/
if ($queryResults->isComplete())
{
$i = 0;
$rows = $queryResults->rows();
foreach ($rows as $row)
{
$i++;
$result[$i] = $row;
}
}
else
{
throw new Exception('The query failed to complete');
}
print_r($result);

Related

How do I authenticate a service account in Google Cloud Services in PHP?

While developing Recaptcha Enterprise for use of the V2 "I am not a robot" checkbox, I am stuck on this error:
Fatal error: Uncaught DomainException: Could not load the default credentials. Browse to https://developers.google.com/accounts/docs/application-default-credentials for more information
I follow the link and have settled on this to authenticate:
use Google\Cloud\Storage\StorageClient;
$storage = new StorageClient([
'keyFile' => json_decode(file_get_contents($path_to_keyfile), true),
'projectId' => 'MY_PROJECT'
]);
I cannot find anything else that suggests I need to do anything more than this, and this link to the constructor API doesn't suggest I can pass it in as a parameter and then proceed. I do not want to use environment variables for this project, I want to connect manually in the code. What am I missing? I can confirm I have a working service account.
If it's helpful, the code I'm trying to run after I presumably authenticate is this:
// ==================== CAPTCHA ===================
use Google\Cloud\RecaptchaEnterprise\V1\RecaptchaEnterpriseServiceClient;
use Google\Cloud\RecaptchaEnterprise\V1\Event;
use Google\Cloud\RecaptchaEnterprise\V1\Assessment;
use Google\Cloud\RecaptchaEnterprise\V1\TokenProperties\InvalidReason;
$captcha_response = $_POST['g-recaptcha-response'];
$site_key = "123456789abc";
$client = new RecaptchaEnterpriseServiceClient();
define('SITE_KEY', $site_key);
define('TOKEN', $captcha_response);
define('PROTECTED_ACTION', 'signup');
define('PARENT_PROJECT', 'projects/MY_PROJECT');
$event = (new Event())
->setSiteKey(SITE_KEY)
->setExpectedAction(PROTECTED_ACTION)
->setToken(TOKEN);
$assessment = (new Assessment())
->setEvent($event);
try {
$response = $client->createAssessment(
PARENT_PROJECT,
$assessment
);
if ($response->getTokenProperties()->getValid() == false) {
printf('The CreateAssessment() call failed because the token was invalid for the following reason: ');
printf(InvalidReason::name($response->getTokenProperties()->getInvalidReason()));
} else {
if ($response->getEvent()->getExpectedAction() == PROTECTED_ACTION) {
printf('The score for the protection action is:');
printf($response->getRiskAnalysis()->getScore());
}
else
{
printf('The action attribute in your reCAPTCHA tag does not match the action you are expecting to score');
}
}
} catch (exception $e) {
printf('CreateAssessment() call failed with the following error: ');
printf($e);
}
Here's how I got it working. Thanks to John Hanley for the help in a previous answer. The documentation had lead me to believe that (for whatever reason) Storage was required, but that was not the case: it was as simple as providing the path to the key via the credentials parameter. Not the keyFile parameter.
if (empty($_POST['g-recaptcha-response']))
die("You have failed the not-a-robot check.");
$captcha_response = $_POST['g-recaptcha-response'];
require 'composer/vendor/autoload.php';
use Google\Cloud\RecaptchaEnterprise\V1\RecaptchaEnterpriseServiceClient;
use Google\Cloud\RecaptchaEnterprise\V1\Event;
use Google\Cloud\RecaptchaEnterprise\V1\Assessment;
use Google\Cloud\RecaptchaEnterprise\V1\TokenProperties\InvalidReason;
$path_to_keyfile = "MY_PROJECT-1234567890abc.json";
$site_key = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
$client = new RecaptchaEnterpriseServiceClient([
'credentials' => $path_to_keyfile,
'projectId' => 'MY_PROJECT'
]);
define('SITE_KEY', $site_key);
define('TOKEN', $captcha_response);
define('PROTECTED_ACTION', 'signup');
define('PARENT_PROJECT', 'projects/MY_PROJECT');
$event = (new Event())
->setSiteKey(SITE_KEY)
->setExpectedAction(PROTECTED_ACTION)
->setToken(TOKEN);
$assessment = (new Assessment())
->setEvent($event);
try {
$response = $client->createAssessment(PARENT_PROJECT, $assessment);
if ($response->getTokenProperties()->getValid() == false) {
printf('The CreateAssessment() call failed because the token was invalid for the following reason: ');
printf(InvalidReason::name($response->getTokenProperties()->getInvalidReason()));
exit;
} else {
if ($response->getEvent()->getExpectedAction() == PROTECTED_ACTION) {
// Closer to 1 = human, to 0 = robot.
$bot_score = $response->getRiskAnalysis()->getScore();
// do what you want with the score here...
} else {
die('The action attribute in your reCAPTCHA tag does not match the action you are expecting to score');
}
}
} catch (exception $e) {
printf('CreateAssessment() call failed with the following error: ');
printf($e);
exit;
}
Your problem is that you are not specifying the service account to use in the client constructor and the system is falling back to using ADC (Application Default Credentials).
ADC will check the environment variable GOOGLE_APPLICATION_CREDENTIALS for the service account JSON key file.
You can set the environment variable before running your program:
Windows:
set GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json
Linux:
export GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json
Or modify your program by changing this line of code:
$client = new RecaptchaEnterpriseServiceClient();
To this:
$options = ['keyFile' => $path_to_keyfile];
$client = new RecaptchaEnterpriseServiceClient($options);
Note 1:
If you are running your program on a Google Cloud computer service such as Compute Engine, App Engine, Cloud Run, ... the default service account will be used if neither of the above methods are implemented.
Note 2:
While developing, another method is to use the CLI's application default credentials. Run the following command using the Google Cloud SDK CLI:
gcloud auth application-default login
However, I have not verified that the reCAPTCHA Enterprise library checks for this type of credential.

storageclient class can't be found?

I'm trying desperately to figure out how to create a simple audio transcription script (for longer audio files) via PHP (the only language I know). I'm getting the error Class 'Google\Cloud\Storage\StorageClient' not found
I'm using the gcloud console code editor and everything should be installed (unless there is a separate composer install just for cloud storage, although I haven't been able to find anything about it in the documentation if there is).
I also entered gcloud auth application-default print-access-token which printed out an access token, but I don't know what (if any) I'm supposed to do with that other than the "set GOOGLE_APPLICATION_CREDENTIALS" command that I copied and pasted into the console shell prompt.
Here's the php code:
<?php
namespace Google\Cloud\Samples\Speech;
require __DIR__ . '/vendor/autoload.php';
use Exception;
# [START speech_transcribe_async_gcs]
use Google\Cloud\Speech\SpeechClient;
use Google\Cloud\Storage\StorageClient;
use Google\Cloud\Core\ExponentialBackoff;
$projectId = 'xxxx';
$speech = new SpeechClient([
'projectId' => $projectId,
'languageCode' => 'en-US',
]);
$filename = "20180925_184741_L.mp3";
# The audio file's encoding and sample rate
$options = [
'encoding' => 'LINEAR16',
'sampleRateHertz' => 16000,
'languageCode' => 'en-US',
'enableWordTimeOffsets' => false,
'enableAutomaticPunctuation' => true,
'model' => 'video',
];
function transcribe_async_gcs($bucketName, $objectName, $languageCode = 'en-US', $options = [])
{
// Create the speech client
$speech = new SpeechClient([
'languageCode' => $languageCode,
]);
// Fetch the storage object
$storage = new StorageClient();
$object = $storage->bucket($bucketName)->object($objectName);
// Create the asyncronous recognize operation
$operation = $speech->beginRecognizeOperation(
$object,
$options
);
// Wait for the operation to complete
$backoff = new ExponentialBackoff(10);
$backoff->execute(function () use ($operation) {
print('Waiting for operation to complete' . PHP_EOL);
$operation->reload();
if (!$operation->isComplete()) {
throw new Exception('Job has not yet completed', 500);
}
});
// Print the results
if ($operation->isComplete()) {
$results = $operation->results();
foreach ($results as $result) {
$alternative = $result->alternatives()[0];
printf('Transcript: %s' . PHP_EOL, $alternative['transcript']);
printf('Confidence: %s' . PHP_EOL, $alternative['confidence']);
}
}
}
# [END speech_transcribe_async_gcs]
transcribe_async_gcs("session_audio", $filename, "en-US", $options);
With apologies, PHP is not a language I'm proficient with but, I suspect you haven't (and must) install the client library for Cloud Storage so that your code may access it. This would explain its report that the Class is missing.
The PHP client library page includes two alternatives. One applies if you're using Composer, the second -- possibly what you want -- a direct download which you'll need to path correctly for your code.
Some time ago, I wrote a short blog post providing a simple example (using Cloud Storage) for each of Google's supported languages. Perhaps it will help you too.

Download files from firebase Storage with php

i am new in firebase web if it possible to upload, download, and delete file using php. i have upload file using JS but i want to download using PHP.
Here is script of download file using JS but i want in PHP.
Thanks in advance...
My Code
[START storage_quickstart]
# Includes the autoloader for libraries installed with composer
require __DIR__ . '/vendor/autoload.php';
# Imports the Google Cloud client library
use Google\Cloud\Storage\StorageClient;
# Your Google Cloud Platform project ID
$projectId = 'My project ID';
# Instantiates a client
$storage = new StorageClient([
'projectId' => $projectId
]);
# The name for the new bucket
$bucketName = 'my bucket';
# Creates the new bucket
$bucket = $storage->createBucket($bucketName);
echo 'Bucket ' . $bucket->name() . ' created.';
# [END storage_quickstart]
return $bucket;
The short answer is that you should use gcloud-php. This requires that you set up a service account (or use Google Compute Engine/Container Engine/App Engine which provide default credentials).
It's likely that you'll create a service account, download a keyfile.json, and provide it as an argument to the StorageClient, like so:
# Instantiates a client
$storage = new StorageClient([
'keyFilePath' => '/path/to/key/file.json',
'projectId' => $projectId
]);
Alternatively, it looks like they've built another layer of abstraction, which takes the same arguments but allows you to use lots of other services:
use Google\Cloud\ServiceBuilder;
$gcloud = new ServiceBuilder([
'keyFilePath' => '/path/to/key/file.json',
'projectId' => 'myProject'
]);
$storage = $gcloud->storage();
$bucket = $storage->bucket('myBucket');
That's an old question, but I was struggling with same problem... hope my solution help someone.
In fact, I really don't know if there is an official way to do that, but I created the method below and it worked for me.
function storageFileUrl($name, $path = []) {
$base = 'https://firebasestorage.googleapis.com/v0/b/';
$projectId = 'your-project-id';
$url = $base.$projectId.'/o/';
if(sizeof($path) > 0) {
$url .= implode('%2F', $path).'%2F';
}
return $url.$name.'?alt=media';
}
To access files in the root of bucket:
$address = storageFileUrl('myFile');
Result: https://firebasestorage.googleapis.com/v0/b/your-project-id.appspot.com/o/myFile?alt=media
To access files inside some folder, do:
$address = storageFileUrl('myFile', ['folder', 'subfolder']);
Result: https://firebasestorage.googleapis.com/v0/b/your-project-id.appspot.com/o/folder%2Fsubfolder%2FmyFile?alt=media
Enjoy.

Openfire RestAPI for PHP Configuration

I am trying to connect to my Openfire Server using RestAPI from Github
Now I have installed RestAPI plugin in Openfire folder.
I am on Centos 7.
<?php
include "vendor/autoload.php";
$api = new \Gnello\OpenFireRestAPI\API();
//Set the required config parameters
$api->Settings()->setSecret("YWRtaW46YWRtaW4");
$api->Settings()->setHost("localhost");
$api->Settings()->setServerName("localhost");
//Default values
$api->Settings()->setPort("9090");
$api->Settings()->setSSL(false);
$api->Settings()->setPlugin("/plugins/restapi/v1");
Now WhenI try to connect it shows error:
if($result['response']) {
echo $result['output'];
} else {
echo 'Error!';
}
In httpd logs it says undefined $result which is obvious.
But I followed the steps as it were mentioned on its repository.
Can Any One please guide me how to use this ?
#Udated
include "vendor/autoload.php";
$api = new \Gnello\OpenFireRestAPI\API();
//Enable debug mode
$api->Settings()->setDebug(true);
$requests = \Gnello\OpenFireRestAPI\Debug\Request::getRequests();
//var_dump($api);
//var_dump($requests);
$result = $api->users();
//var_dump($api);
$username ="test2";
$results = $api->getuser($username);
if($result['response'])
{
echo $result['output'];
}
else
{
echo 'Error!';
}
https://github.com/gnello/php-openfire-restapi
Easy Php REST API Client for the Openfire REST API Plugin which provides the ability to manage Openfire instance by sending an REST/HTTP request to the server
Please read documentation for further information on using this application.
Installation
composer require gnello/php-openfire-restapi
Authentication
There are two ways to authenticate:
Basic HTTP Authentication
$authenticationToken = new \Gnello\OpenFireRestAPI\AuthenticationToken('your_user', 'your_password');
Shared secret key
$authenticationToken = new \Gnello\OpenFireRestAPI\AuthenticationToken('your_secret_key');
Start
$api = new \Gnello\OpenFireRestAPI\API('your_host', 9090, $authenticationToken);
Users
//Add a new user
$properties = array('key1' => 'value1', 'key2' => 'value2');
$result = $api->Users()->createUser('Username', 'Password', 'Full Name', 'email#domain.com', $properties);
//Delete a user
$result = $api->Users()->deleteUser('Username');
//Ban a user
$result = $api->Users()->lockoutUser('Username');
//Unban a user
$result = $api->Users()->unlockUser('Username');
Then print Result.
Open Link Fore more.
https://github.com/gnello/php-openfire-restapi

Download CSV file using Google Drive V3(V2 works perfect) throws error 403

I m using DRIVE V2 WITH Service Account to download CSV file,This one is working fine. I want to migrate DRIVE V2 to DRIVE V3 .So i changed my script as per below google documents
I. Download a file in drive V3
PHP Library & Drive API V3 used in this sample:
1.Sample script download CSV file using Drive V3
Method used: Using alt=media
Reason: this method only available in DRIVE V3
<?php
set_include_path( get_include_path() . PATH_SEPARATOR . 'Google' );
require_once 'Google/autoload.php';
require_once 'Google/Client.php';
require_once 'Google/Service/Drive.php';
try{
//Get service document
$service = get_service_document();
//Download a csv file
$data = $service->files->get("FILE ID", array( 'alt' => 'media'));
print_r($data);
}
catch(Exception $e){
print_r($e->getMessage());
}
//function to get service
function get_service_document(){
$userstamp='user#example.com';
//Enable below two lines if let know the clientid,tokens,etc.,
$driveService=buildServiceDrive($userstamp,"SERVICE_ACCOUNT","https://www.googleapis.com/auth/drive","KEY.p12");
return $driveService;
}
//building service
function buildServiceDrive($userEmail,$service_id,$scope,$service_filename) {
$key = file_get_contents($service_filename);
$auth = new Google_Auth_AssertionCredentials(
$service_id,
array($scope),
$key);
$auth->sub = $userEmail;
$client = new Google_Client();
$client->setAssertionCredentials($auth);
return new Google_Service_Drive($client);
}
RESULT:
I got the below issue
Error calling GET https://www.googleapis.com/drive/v3/files/0B5pkfK_IBDxjeHlTTDFFY01CXzQ?alt=media: (302)
Moved Temporarily
The document has moved here.
After clicked here. I saw below error.
{
"error": {
"errors": [
{
"domain": "usageLimits",
"reason": "dailyLimitExceededUnreg",
"message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup.",
"extendedHelp": "https://code.google.com/apis/console"
}
],
"code": 403,
"message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup."
}
}
II. Download a file in Drive V2
I used alternate method to download CSV file from drive.
PHP Library & Drive API V2 used in this sample:
2.Sample Script download CSV file using Drive V2
Method used : Alternate method: using downloadUrl
<?php
set_include_path( get_include_path() . PATH_SEPARATOR . 'Google' );
require_once 'Google/autoload.php';
require_once 'Google/Client.php';
require_once 'Google/Service/Drive.php';
try{
//Get service document
$service = get_service_document();
$data = $service->files->get("FILE ID");
$url=$data->downloadUrl;
$data=downloadFile($service,$url);
print_r($data);
}
catch(Exception $e){
print_r($e->getMessage());
}
//Alternate method using download URL
function downloadFile($service, $downloadUrl)
{
if ($downloadUrl) {
$request = new Google_Http_Request($downloadUrl, 'GET', null, null);
$httpRequest = $service->getClient()->getAuth()->authenticatedRequest($request);
if ($httpRequest->getResponseHttpCode() == 200) {
return $httpRequest->getResponseBody();
} else {
echo "errr";
return null;
}
} else {
echo "empty";
return null;
}
}
//function to get service
function get_service_document(){
$driveService =buildServiceDrive(user#example.com',"SERVICE-ACCOUNT","https://www.googleapis.com/auth/drive","KEY.p12");
return $driveService;
}
//building service
function buildServiceDrive($userEmail,$service_id,$scope,$service_filename) {
$key = file_get_contents($service_filename);
$auth = new Google_Auth_AssertionCredentials(
$service_id,
array($scope),
$key);
$auth->sub = $userEmail;
$client = new Google_Client();
$client->setAssertionCredentials($auth);
return new Google_Service_Drive($client);
}
Result:
i got CSV file records, working fine
Plz help me resolve to download a CSV file using G DRIVE V3. Is there any regression or functions lagging b/w V2, V3?
Since the Google Drive API for PHP is beta version, realize that some errors can be experienced by developers.
Error calling GET
https://www.googleapis.com/drive/v3/files/0B5pkfK_IBDxjeHlTTDFFY01CXzQ?alt=media:
(302) Moved Temporarily The document has moved here.
In this case, here's link is:
https://www.googleapis.com/download/drive/v3/files/0B5pkfK_IBDxjeHlTTDFFY01CXzQ?alt=media
You can see the API Server suggest the new link "download" before "/drive...".
In Google Drive Client Library V3, here is the solution you can fix manually by adding the following code to src/Google/Http/REST.php after line 147:
if($requestUrl=='drive/v3/files/{fileId}' && $params['alt']['value']=='media')
$requestUrl = "download/".$requestUrl;
Hope this help... :)

Categories