title: Google API fetching data error
body: <p>When loading the token script :
  token.php</p>
  
  <p><div class="snippet" data-lang="js" data-hide="true" data-console="true" data-babel="false">
  <div class="snippet-code snippet-currently-hidden">
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;?php
  
  require_once 'vendor/autoload.php';
  
  session_start();
  
  /*
   * You can acquire an OAuth 2.0 client ID and client secret from the
   * {{ Google Cloud Console }} &lt;{{ https://cloud.google.com/console }}&gt;
   * For more information about using OAuth 2.0 to access Google APIs, please see:
   * &lt;https://developers.google.com/youtube/v3/guides/authentication&gt;
   * Please ensure that you have enabled the YouTube Data API for your project.
   */
  $OAUTH2_CLIENT_ID = '516195178663-5pgnd88unc38khttmgj67scinlhk7caf.apps.googleusercontent.com'; // Enter your Client ID here
  $OAUTH2_CLIENT_SECRET = 'QLsIeOBhHLIee4_d-OOqjblK'; // Enter your Client Secret here
  $REDIRECT = filter_var('http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'], FILTER_SANITIZE_URL);
  $APPNAME = "BrickFame";
  
  $client = new Google_Client();
  $client-&gt;setClientId($OAUTH2_CLIENT_ID);
  $client-&gt;setClientSecret($OAUTH2_CLIENT_SECRET);
  $client-&gt;setScopes('https://www.googleapis.com/auth/youtube');
  $client-&gt;setRedirectUri($REDIRECT);
  $client-&gt;setApplicationName($APPNAME);
  $client-&gt;setAccessType('offline');
  $client-&gt;setApprovalPrompt('force');
      
  // Define an object that will be used to make all API requests.
  $youtube = new Google_Service_YouTube($client);
  
  if (isset($_GET['code'])) {
      if (strval($_SESSION['state']) !== strval($_GET['state'])) {
          die('The session state did not match.');
      }
  
      $client-&gt;authenticate($_GET['code']);
      $_SESSION['token'] = $client-&gt;getAccessToken();
  }
  
  if (isset($_SESSION['token'])) {
      $client-&gt;setAccessToken($_SESSION['token']);
      echo "Access Token: " . json_encode($_SESSION['token']);
  }
  
  // Check to ensure that the access token was successfully acquired.
  if ($client-&gt;getAccessToken()) {
      try {
          // Call the channels.list method to retrieve information about the
          // currently authenticated user's channel.
          $channelsResponse = $youtube-&gt;channels-&gt;listChannels('contentDetails', array('mine' =&gt; 'true'));
  
          $htmlBody = '';
          foreach ($channelsResponse['items'] as $channel) {
              // Extract the unique playlist ID that identifies the list of videos
              // uploaded to the channel, and then call the playlistItems.list method
              // to retrieve that list.
              $uploadsListId = $channel['contentDetails']['relatedPlaylists']['uploads'];
  
              $playlistItemsResponse = $youtube-&gt;playlistItems-&gt;listPlaylistItems('snippet', array(
                  'playlistId' =&gt; $uploadsListId,
                  'maxResults' =&gt; 50
              ));
  
              $htmlBody .= "&lt;h3&gt;Videos in list $uploadsListId&lt;/h3&gt;&lt;ul&gt;";
              foreach ($playlistItemsResponse['items'] as $playlistItem) {
                  $htmlBody .= sprintf('&lt;li&gt;%s (%s)&lt;/li&gt;', $playlistItem['snippet']['title'],
                      $playlistItem['snippet']['resourceId']['videoId']);
              }
              $htmlBody .= '&lt;/ul&gt;';
          }
      } catch (Google_ServiceException $e) {
          $htmlBody .= sprintf('&lt;p&gt;A service error occurred: &lt;code&gt;%s&lt;/code&gt;&lt;/p&gt;',
              htmlspecialchars($e-&gt;getMessage()));
      } catch (Google_Exception $e) {
          $htmlBody .= sprintf('&lt;p&gt;An client error occurred: &lt;code&gt;%s&lt;/code&gt;&lt;/p&gt;',
              htmlspecialchars($e-&gt;getMessage()));
      }
  
      $_SESSION['token'] = $client-&gt;getAccessToken();
  } else {
      $state = mt_rand();
      $client-&gt;setState($state);
      $_SESSION['state'] = $state;
  
      $authUrl = $client-&gt;createAuthUrl();
      $htmlBody = &lt;&lt;&lt;END
  &lt;h3&gt;Authorization Required&lt;/h3&gt;
  &lt;p&gt;You need to &lt;a href="$authUrl"&gt;authorise access&lt;/a&gt; before proceeding.&lt;p&gt;
  END;
  }
  ?&gt;
   
  &lt;!doctype html&gt;
  &lt;html&gt;
  &lt;head&gt;
      &lt;title&gt;My Uploads&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
  &lt;?php echo $htmlBody;?&gt;
  &lt;/body&gt;
  &lt;/html&gt;</code></pre>
  </div>
  </div>
  </p>
  
  <p>I can fetch my access token and refresh token is shown and i saved it under token.txt</p>
  
  <p><div class="snippet" data-lang="js" data-hide="true" data-console="true" data-babel="false">
  <div class="snippet-code snippet-currently-hidden">
  <pre class="snippet-code-html lang-html prettyprint-override"><code>Access Token: {"access_token":"ya29.Ci8tA-3KvN7LE03mLLWsJJOsKHPr3ArvEw9xDaCX8wpFxGM-VpLswYwR1Mnhc7wS1Q","token_type":"Bearer","expires_in":3600,"refresh_token":"1\/BopX8bClCDuDkg0WO9KKyvxKMC-y1GiFhFOO8JQ5HkU","created":1469621552}</code></pre>
  </div>
  </div>
  </p>
  
  <p>However when accessing the upload script:
  api.php </p>
  
  <p><div class="snippet" data-lang="js" data-hide="true" data-console="true" data-babel="false">
  <div class="snippet-code snippet-currently-hidden">
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;?php
  
  $key = file_get_contents('token.txt');
  
  require_once 'vendor/autoload.php';
  $client_id = '516195178663-5pgnd88unc38khttmgj67scinlhk7caf.apps.googleusercontent.com'; // Enter your Client ID here
  $client_secret = 'QLsIeOBhHLIee4_d-OOqjblK'; // Enter your Client Secret here
  $videoPath = "videos/example.mkv";
  $videoTitle = "Just an Example Title";
  $videoDescription = "This is the YouTube video's description";
  $videoCategory = "22";
  $videoTags = array("first tag","second tag","third tag");
  
  try{
      // Client init
      $client = new Google_Client();
      $client-&gt;setClientId($client_id);
      $client-&gt;setAccessType('offline');
      $client-&gt;setApprovalPrompt('force');
      $client-&gt;setAccessToken($key);
      $client-&gt;setClientSecret($client_secret);
  
      if ($client-&gt;getAccessToken()) {
          /**
           * Check to see if our access token has expired. If so, get a new one and save it to file for future use.
           */
          if($client-&gt;isAccessTokenExpired()) {
              $newToken = json_decode($client-&gt;getAccessToken());
              $client-&gt;refreshToken($newToken-&gt;refresh_token);
              file_put_contents($key, $client-&gt;getAccessToken());
          }
   
          $youtube = new Google_Service_YouTube($client);
   
          // Create a snipet with title, description, tags and category id
          $snippet = new Google_Service_YouTube_VideoSnippet();
          $snippet-&gt;setTitle($videoTitle);
          $snippet-&gt;setDescription($videoDescription);
          $snippet-&gt;setCategoryId($videoCategory);
          $snippet-&gt;setTags($videoTags);
          $snippet-&gt;setDefaultLanguage("en");
          $snippet-&gt;setDefaultAudioLanguage("en");
  
          $recordingDetails = new Google_Service_YouTube_VideoRecordingDetails();
          $recordingDetails-&gt;setLocationDescription("United States of America");
          $recordingDetails-&gt;setRecordingDate("2016-01-20T12:34:00.000Z");
          $locationdetails = new Google_Service_YouTube_GeoPoint();
          $locationdetails-&gt;setLatitude("38.8833");
          $locationdetails-&gt;setLongitude("77.0167");
          $recordingDetails-&gt;setLocation($locationdetails);
  
          // Create a video status with privacy status. Options are "public", "private" and "unlisted".
          $status = new Google_Service_YouTube_VideoStatus();
          $status-&gt;setPrivacyStatus("public");
          $status-&gt;setPublicStatsViewable(false);
          $status-&gt;setEmbeddable(false); // Google defect still not editable https://code.google.com/p/gdata-issues/issues/detail?id=4861
   
          // Create a YouTube video with snippet and status
          $video = new Google_Service_YouTube_Video();
          $video-&gt;setSnippet($snippet);
          $video-&gt;setRecordingDetails($recordingDetails);
          $video-&gt;setStatus($status);
   
          // Size of each chunk of data in bytes. Setting it higher leads faster upload (less chunks,
          // for reliable connections). Setting it lower leads better recovery (fine-grained chunks)
          $chunkSizeBytes = 1 * 1024 * 1024;
  
          // Setting the defer flag to true tells the client to return a request which can be called
          // with -&gt;execute(); instead of making the API call immediately.
          $client-&gt;setDefer(true);
  
          // Create a request for the API's videos.insert method to create and upload the video.
          $insertRequest = $youtube-&gt;videos-&gt;insert("status,snippet,recordingDetails", $video);
  
          // Create a MediaFileUpload object for resumable uploads.
          $media = new Google_Http_MediaFileUpload(
              $client,
              $insertRequest,
              'video/*',
              null,
              true,
              $chunkSizeBytes
          );
          $media-&gt;setFileSize(filesize($videoPath));
  
          // Read the media file and upload it chunk by chunk.
          $status = false;
          $handle = fopen($videoPath, "rb");
          while (!$status &amp;&amp; !feof($handle)) {
              $chunk = fread($handle, $chunkSizeBytes);
              $status = $media-&gt;nextChunk($chunk);
          }
  
          fclose($handle);
  
          /**
           * Video has successfully been uploaded, now lets perform some cleanup functions for this video
           */
          if ($status-&gt;status['uploadStatus'] == 'uploaded') {
              // Actions to perform for a successful upload
          }
  
          // If you want to make other calls after the file upload, set setDefer back to false
          $client-&gt;setDefer(true);
  
      } else{
          // @TODO Log error
          echo 'Problems creating the client';
      }
  
  } catch(Google_Service_Exception $e) {
      print "Caught Google service Exception ".$e-&gt;getCode(). " message is ".$e-&gt;getMessage();
      print "Stack trace is ".$e-&gt;getTraceAsString();
  }catch (Exception $e) {
      print "Caught Google service Exception ".$e-&gt;getCode(). " message is ".$e-&gt;getMessage();
      print "Stack trace is ".$e-&gt;getTraceAsString();
  }
  
  ?&gt;</code></pre>
  </div>
  </div>
  
  It is when i encountered the error : Here is the return value</p>
  
  <p><div class="snippet" data-lang="js" data-hide="true" data-console="true" data-babel="false">
  <div class="snippet-code snippet-currently-hidden">
  <pre class="snippet-code-html lang-html prettyprint-override"><code>Caught Google service Exception 0 message is refresh token must be passed in or set as part of setAccessTokenStack trace is #0 /home/vol11_2/freecluster.eu/fceu_18534127/htdocs/vendor/google/apiclient/src/Google/Client.php(246): Google_Client-&gt;fetchAccessTokenWithRefreshToken(NULL) #1 /home/vol11_2/freecluster.eu/fceu_18534127/htdocs/api.php(29): Google_Client-&gt;refreshToken(NULL) #2 {main}</code></pre>
  </div>
  </div>
  </p>
  
  <p>What might i have missed? Could it be possibly my files error?
  I dont understand the line that says : refresh token must be passed in or set as part of setAccessTokenStack trace is #0 </p>
  
  <p>Can anyone guide me out? 
  Thanks ! :)</p>