使用Google Drive API更新文件/文件夹返回403错误求助
问题分析
错误403 fieldNotWritable的核心原因:你使用listFiles或get方法返回的完整DriveFile对象调用update接口,这些对象包含大量Google Drive API标记为只读的字段(比如createdTime、owners、fileExtension等),当把整个对象传给update时,API会拒绝修改这些不可写字段,从而抛出错误。
解决方案
1. 文件夹移入回收站的修正代码
不要直接修改查询返回的folder对象,而是创建一个仅包含需要修改字段的新DriveFile实例:
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())) { $folder = Util::arrayGetValue($res->getFiles(), 0); // 创建仅包含修改字段的新DriveFile对象 $updateFile = new \Google\Service\Drive\DriveFile(); $updateFile->setTrashed(true); // 或使用setExplicitlyTrashed(true),按需选择 // 调用update时仅传入新对象,可指定返回字段减少数据传输 $service->files->update($folder->getId(), $updateFile, [ 'fields' => 'id,trashed' ]); } }
2. 日志文件更新的修正代码
同样,不要直接传入查询返回的file对象,而是创建新的空DriveFile实例(仅更新文件内容,不修改元数据):
[...] $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" ]; // 创建空DriveFile对象,仅更新文件内容 $updateFile = new \Google\Service\Drive\DriveFile(); $file = $service->files->update($file->getId(), $updateFile, $optParams);
关键注意事项
- 仅传递需要修改的字段:Google Drive API的
update接口要求请求体只包含需修改的字段,禁止传递完整资源对象,否则会触发只读字段错误。 - 权限验证:你已申请的
drive权限足够完成操作,权限不是问题核心。 - 字段选择:
trashed是通用移入回收站字段,explicitlyTrashed用于区分直接删除/因父文件夹删除间接移入,根据业务场景选择即可。
内容的提问来源于stack exchange,提问作者Neo710
相关产品推荐
相关产品推荐

