Search code examples
phpgoogle-drive-apigoogle-api-php-client

Google Drive API update file or folders returns 403


I'm using google-api-php-client and I'm trying to move a folder in the trash. The folder was created from my app, I can upload/create files inside and I can delete it without matters, but I can not call the updete method even on it or any other file/folders.

Those are the scopes that I request at login time: https://www.googleapis.com/auth/drive, https://www.googleapis.com/auth/drive.file, https://www.googleapis.com/auth/drive.metadata

And this is my code:

public function deleteObjectFolder($object, ExternalResource $resource) {
  $folderName = static::buildFolderName($object);

  if (!($client = $this->getClient($resource))) {
    return new Response("refreshTokenExpiredOrTokenRevoked", Response::HTTP_UNPROCESSABLE_ENTITY);
  }

  $service = new \Google\Service\Drive($client);

  $res = $service->files->listFiles([
    "q" => "mimeType = 'application/vnd.google-apps.folder' and name = '$folderName' and trashed = false"
  ]);

  if (count($res->getFiles())) {
    /** @var \Google\Service\Drive\DriveFile $folder */
    $folder = Util::arrayGetValue($res->getFiles(), 0);
    // $folder->setTrashed(true);
    $folder->setExplicitlyTrashed(true);
    $service->files->update($folder->getId(), $folder);
  }
}

Even if I use setTrashed or setExplicitlyTrashed, when the code executes the update method returns this error:

{
  "error": {
    "code": 403,
    "message": "The resource body includes fields which are not directly writable.",
    "errors": [{
      "message": "The resource body includes fields which are not directly writable.",
      "domain": "global",
      "reason": "fieldNotWritable"
    }]
  }
}

The same thing appens with a log file inside the folder, also created regularly by the app itself. Code:

[...]
$file = Util::arrayGetValue($res->getFiles(), 0);
$content = $service->files->get($file->getId(), ["alt" => "media"]);
$content = $content->getBody()->getContents();
[...]
$logger = (new FileLogger())
  ->setAction($action)
  ->setDateTime(new DateTimeImmutable())
  ->setLevel($level)
  ->setMessage($message);

$content .= "\n{$logger->toString()}";
$optParams = [
  "data" => $content,
  "fields" => "id",
  "uploadType" => "multipart"
];
$file = $service->files->update($file->getId(), $file, $optParams);

Any ideas? Thanks to all


Solution

  • First, from your search query, I guessed that you are using Drive API v3. And, the official document of explicitlyTrashed says as follows. Ref

    Whether the file has been explicitly trashed, as opposed to recursively trashed from a parent folder.

    I thought that this might be the reason for your current issue. When you want to move the file to the trash box, please use trashed. When this is reflected in your script, how about the following modification?

    From:

    $folder->setExplicitlyTrashed(true);
    

    To:

    $folder->setTrashed(true);
    

    Or, if the above modification was not useful, how about the following script?

    $folderId = "###"; // Please set your folder ID of the folder you want to move to the trash box.
    $metadata = new \Google_Service_Drive_DriveFile(["trashed" => true]);
    $service->files->update($folderId, $metadata);
    

    References: