Error while using google analytics reporting api v4
<p>I am trying to use google analytics reporting api v4 and I did every step as it said in this link : <a href="https://developers.google.com/analytics/devguides/reporting/core/v4/quickstart/service-php" rel="nofollow">reporting api v4</a></p>

<p>now I am getting this error:</p>

<pre><code>Fatal error: Uncaught exception 'Google_Service_Exception' with message '{ "error": "invalid_grant", "error_description": "Invalid JWT Signature." } ' in C:\xampp\htdocs\gaapi\vendor\google\apiclient\src\Google\Http\REST.php:118 Stack trace: #0 C:\xampp\htdocs\gaapi\vendor\google\apiclient\src\Google\Http\REST.php(94): Google_Http_REST::decodeHttpResponse(Object(GuzzleHttp\Psr7\Response), Object(GuzzleHttp\Psr7\Request), 'Google_Service_...') #1 [internal function]: Google_Http_REST::doExecute(Object(GuzzleHttp\Client), Object(GuzzleHttp\Psr7\Request), 'Google_Service_...') #2 C:\xampp\htdocs\gaapi\vendor\google\apiclient\src\Google\Task\Runner.php(181): call_user_func_array(Array, Array) #3 C:\xampp\htdocs\gaapi\vendor\google\apiclient\src\Google\Http\REST.php(58): Google_Task_Runner-&gt;run() #4 C:\xampp\htdocs\gaapi\vendor\google\apiclient\src\Google\Client.php(779): Google_Http_REST::execute(Object(GuzzleHttp\Client), Object(GuzzleHttp\Psr7\Request), 'Google_Service_...', Array) #5 C:\xampp\htdocs\gaapi\vendor\google\a in C:\xampp\htdocs\gaapi\vendor\google\apiclient\src\Google\Http\REST.php on line 118
</code></pre>

<p>and this is rest.php that i am getting this error from:</p>

<pre><code>   &lt;?php
/*
 * Copyright 2010 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

use Google\Auth\HttpHandler\HttpHandlerFactory;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Psr7\Response;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;

/**
 * This class implements the RESTful transport of apiServiceRequest()'s
 */
class Google_Http_REST
{
  /**
   * Executes a Psr\Http\Message\RequestInterface and (if applicable) automatically retries
   * when errors occur.
   *
   * @param Google_Client $client
   * @param Psr\Http\Message\RequestInterface $req
   * @return array decoded result
   * @throws Google_Service_Exception on server side error (ie: not authenticated,
   *  invalid or malformed post body, invalid url)
   */
  public static function execute(
      ClientInterface $client,
      RequestInterface $request,
      $expectedClass = null,
      $config = array(),
      $retryMap = null
  ) {
    $runner = new Google_Task_Runner(
        $config,
        sprintf('%s %s', $request-&gt;getMethod(), (string) $request-&gt;getUri()),
        array(get_class(), 'doExecute'),
        array($client, $request, $expectedClass)
    );

    if (!is_null($retryMap)) {
      $runner-&gt;setRetryMap($retryMap);
    }

    return $runner-&gt;run();
  }

  /**
   * Executes a Psr\Http\Message\RequestInterface
   *
   * @param Google_Client $client
   * @param Psr\Http\Message\RequestInterface $request
   * @return array decoded result
   * @throws Google_Service_Exception on server side error (ie: not authenticated,
   *  invalid or malformed post body, invalid url)
   */
  public static function doExecute(ClientInterface $client, RequestInterface $request, $expectedClass = null)
  {
    try {
      $httpHandler = HttpHandlerFactory::build($client);
      $response = $httpHandler($request);
    } catch (RequestException $e) {
      // if Guzzle throws an exception, catch it and handle the response
      if (!$e-&gt;hasResponse()) {
        throw $e;
      }

      $response = $e-&gt;getResponse();
      // specific checking for Guzzle 5: convert to PSR7 response
      if ($response instanceof \GuzzleHttp\Message\ResponseInterface) {
        $response = new Response(
            $response-&gt;getStatusCode(),
            $response-&gt;getHeaders() ?: [],
            $response-&gt;getBody(),
            $response-&gt;getProtocolVersion(),
            $response-&gt;getReasonPhrase()
        );
      }
    }

    return self::decodeHttpResponse($response, $request, $expectedClass);
  }

  /**
   * Decode an HTTP Response.
   * @static
   * @throws Google_Service_Exception
   * @param Psr\Http\Message\RequestInterface $response The http response to be decoded.
   * @param Psr\Http\Message\ResponseInterface $response
   * @return mixed|null
   */
  public static function decodeHttpResponse(
      ResponseInterface $response,
      RequestInterface $request = null,
      $expectedClass = null
  ) {
    $code = $response-&gt;getStatusCode();

    // retry strategy
    if ((intVal($code)) &gt;= 400) {
      // if we errored out, it should be safe to grab the response body
      $body = (string) $response-&gt;getBody();

      // Check if we received errors, and add those to the Exception for convenience
      throw new Google_Service_Exception($body, $code, null, self::getResponseErrors($body));
    }

    // Ensure we only pull the entire body into memory if the request is not
    // of media type
    $body = self::decodeBody($response, $request);

    if ($expectedClass = self::determineExpectedClass($expectedClass, $request)) {
      $json = json_decode($body, true);

      return new $expectedClass($json);
    }

    return $response;
  }

  private static function decodeBody(ResponseInterface $response, RequestInterface $request = null)
  {
    if (self::isAltMedia($request)) {
      // don't decode the body, it's probably a really long string
      return '';
    }

    return (string) $response-&gt;getBody();
  }

  private static function determineExpectedClass($expectedClass, RequestInterface $request = null)
  {
    // "false" is used to explicitly prevent an expected class from being returned
    if (false === $expectedClass) {
      return null;
    }

    // if we don't have a request, we just use what's passed in
    if (is_null($request)) {
      return $expectedClass;
    }

    // return what we have in the request header if one was not supplied
    return $expectedClass ?: $request-&gt;getHeaderLine('X-Php-Expected-Class');
  }

  private static function getResponseErrors($body)
  {
    $json = json_decode($body, true);

    if (isset($json['error']['errors'])) {
      return $json['error']['errors'];
    }

    return null;
  }

  private static function isAltMedia(RequestInterface $request = null)
  {
    if ($request &amp;&amp; $qs = $request-&gt;getUri()-&gt;getQuery()) {
      parse_str($qs, $query);
      if (isset($query['alt']) &amp;&amp; $query['alt'] == 'media') {
        return true;
      }
    }

    return false;
  }
}
</code></pre>

<p>and this is the php file that is calling the API:</p>

<pre><code>   &lt;?php

// Load the Google API PHP Client Library.
require_once __DIR__ . '/vendor/autoload.php';

$analytics = initializeAnalytics();
$response = getReport($analytics);
printResults($response);

function initializeAnalytics()
{
  // Creates and returns the Analytics Reporting service object.

  // Use the developers console and download your service account
  // credentials in JSON format. Place them in this directory or
  // change the key file location if necessary.
  $KEY_FILE_LOCATION = __DIR__ . '/DMCwizard-90f81ab1b049.json';

  // Create and configure a new client object.
  $client = new Google_Client();
  $client-&gt;setApplicationName("Hello Analytics Reporting");
  $client-&gt;setAuthConfig($KEY_FILE_LOCATION);
  $client-&gt;setScopes(['https://www.googleapis.com/auth/analytics.readonly']);
  $analytics = new Google_Service_AnalyticsReporting($client);

  return $analytics;
}

function getReport(&amp;$analytics) {

  // Replace with your view ID, for example XXXX.
  $VIEW_ID = "123747116";

  // Create the DateRange object.
  $dateRange = new Google_Service_AnalyticsReporting_DateRange();
  $dateRange-&gt;setStartDate("7daysAgo");
  $dateRange-&gt;setEndDate("today");

  // Create the Metrics object.
  $sessions = new Google_Service_AnalyticsReporting_Metric();
  $sessions-&gt;setExpression("ga:sessions");
  $sessions-&gt;setAlias("sessions");

  // Create the ReportRequest object.
  $request = new Google_Service_AnalyticsReporting_ReportRequest();
  $request-&gt;setViewId($VIEW_ID);
  $request-&gt;setDateRanges($dateRange);
  $request-&gt;setMetrics(array($sessions));

  $body = new Google_Service_AnalyticsReporting_GetReportsRequest();
  $body-&gt;setReportRequests( array( $request) );
  return $analytics-&gt;reports-&gt;batchGet( $body );
}

function printResults(&amp;$reports) {
  for ( $reportIndex = 0; $reportIndex &lt; count( $reports ); $reportIndex++ ) {
    $report = $reports[ $reportIndex ];
    $header = $report-&gt;getColumnHeader();
    $dimensionHeaders = $header-&gt;getDimensions();
    $metricHeaders = $header-&gt;getMetricHeader()-&gt;getMetricHeaderEntries();
    $rows = $report-&gt;getData()-&gt;getRows();

    for ( $rowIndex = 0; $rowIndex &lt; count($rows); $rowIndex++) {
      $row = $rows[ $rowIndex ];
      $dimensions = $row-&gt;getDimensions();
      $metrics = $row-&gt;getMetrics();
      for ($i = 0; $i &lt; count($dimensionHeaders) &amp;&amp; $i &lt; count($dimensions); $i++) {
        print($dimensionHeaders[$i] . ": " . $dimensions[$i] . "\n");
      }

      for ($j = 0; $j &lt; count( $metricHeaders ) &amp;&amp; $j &lt; count( $metrics ); $j++) {
        $entry = $metricHeaders[$j];
        $values = $metrics[$j];
        print("Metric type: " . $entry-&gt;getType() . "\n" );
        for ( $valueIndex = 0; $valueIndex &lt; count( $values-&gt;getValues() ); $valueIndex++ ) {
          $value = $values-&gt;getValues()[ $valueIndex ];
          print($entry-&gt;getName() . ": " . $value . "\n");
        }
      }
    }
  }

}
</code></pre>

<p>if you need me to upload other files for you just let me know.</p>