我看不到使用 php 在我的 Google Drive 中通过 api 创建的文件和文件夹

Posted

技术标签:

【中文标题】我看不到使用 php 在我的 Google Drive 中通过 api 创建的文件和文件夹【英文标题】:I can't see the files and folders created via api in my Google Drive using php 【发布时间】:2016-12-01 13:56:47 【问题描述】:

我正在尝试使用 google drive api 创建文件夹。我能够在最后获得文件ID。但我无法在谷歌驱动器中找到我的文件夹。似乎有些权限问题?

$scopes = array(
    'https://www.googleapis.com/auth/drive',
    'https://www.googleapis.com/auth/drive.appdata','https://www.googleapis.com/auth/drive.apps.readonly',
    'https://www.googleapis.com/auth/drive.metadata','https://www.googleapis.com/auth/drive.file',
    'https://www.googleapis.com/auth/drive.readonly','https://www.googleapis.com/auth/drive.photos.readonly'
);
$creds = new Google_Auth_AssertionCredentials(
    $serviceAccountName,
    $scopes,
    file_get_contents($keyFile)
);
$client = new Google_Client();
$client->setApplicationName($appName);
$client->setClientId($clientId);
$client->setAssertionCredentials($creds);
$service = new Google_Service_Drive($client);
$fileMetadata = new Google_Service_Drive_DriveFile(array(
  'name' => 'Invoices',
  'permissions' => array('type'=>'anyone','role'=>'reader','allowFileDiscovery'=>1),

  'mimeType' => 'application/vnd.google-apps.folder'));
$file = $service->files->create($fileMetadata, array());

printf("File ID: %s\n", $file->id);

【问题讨论】:

【参考方案1】:

正在创建的文件属于 API 帐户电子邮件(类似于api-service-account@yourproject.iam.gserviceaccount.com。如果您转到驱动器 URL: https://docs.google.com/document/d/ID,你会得到一个“权限被拒绝,请求访问”页面。

服务帐户电子邮件与您的用户电子邮件无关。

为了与您的用户创建文件,您需要创建一个 OAauth 令牌授权。

    按照this page 上的“步骤 1:打开 Drive API”步骤创建 OAuth 凭据

    修改你的脚本,按照this page的例子,你可以:


use Google_Client;
use Google_Service_Drive;
use Google_Service_Drive_DriveFile;

...

$file = 'root/to/your/credentials.json';

$client = new Google_Client();
$client->setScopes([
    'https://www.googleapis.com/auth/drive',
    'https://www.googleapis.com/auth/drive.appdata',
    'https://www.googleapis.com/auth/drive.apps.readonly',
    'https://www.googleapis.com/auth/drive.metadata',
    'https://www.googleapis.com/auth/drive.file',
    'https://www.googleapis.com/auth/drive.readonly',
    'https://www.googleapis.com/auth/drive.photos.readonly'
]);

$client->setAuthConfig($file);
$authUrl = $client->createAuthUrl();

printf("Open the following link in your browser:\n%s\n", $authUrl);

// You will need to open this url
print 'Enter verification code: ';
$authCode = trim(fgets(STDIN));

$accessToken = $client->authenticate($authCode);

file_put_contents($credentialsPath, $accessToken);
printf("Credentials saved to %s\n", $credentialsPath);

$client->setAccessToken(json_decode($accessToken, true));

$service = new Google_Service_Drive($client);

$metadata = new Google_Service_Drive_DriveFile([
    'name' => 'testing drive',
    'mimeType' => "application/vnd.google-apps.document"
]);
$file = $service->files->create($metadata, []);
print_r($file);

该文件应位于您的云端硬盘主目录中。

顺便说一句,我建议你试试新版本google/apiclient:2.0.2(它仍处于测试阶段,但工作正常)。

【讨论】:

【参考方案2】:

Mayrop 的回答部分正确。

正在创建的文件属于 API 帐户电子邮件(类似于 api-service-account@yourproject.iam.gserviceaccount.com。

您需要向该帐户的所有者授予权限,例如

    $newPermission = new Google_Service_Drive_Permission();
$value="email id";
$type="user";
$role="writer";
  $newPermission->setValue($value);
  $newPermission->setType($type);
  $newPermission->setRole($role);
 try 
   $res= $service->permissions->insert($fileId, $newPermission);
    print_r($res); 
   catch (Exception $e) 
    print "An error occurred: " . $e->getMessage();
  

您将在与我共享中看到该文件夹​​。您也可以手动添加驱动器。

您还可以使用

禁用通过电子邮件发送通知
$service->permissions->insert($fileId, $newPermission,array('sendNotificationEmails'=>false));

希望这对你有用。

【讨论】:

在使用此代码时,我正在调用未定义的方法 Google_Service_Drive_Permission::setValue() ?为什么会这样? @RamanSall 使用:$newPermission->setEmailAddress($value);我还在这里写了对我有用的完整答案以获取更多详细信息。【参考方案3】:

是的,似乎权限问题。尝试删除

'permissions' => array('type'=>'anyone','role'=>'reader','allowFileDiscovery'=>1),

来自

$fileMetadata = new Google_Service_Drive_DriveFile(array( 'name' => 'Invoices', 'permissions' => array('type'=>'anyone','role'=>'reader','allowFileDiscovery'=>1), 'mimeType' => 'application/vnd.google-apps.folder'));

【讨论】:

【参考方案4】:

所以我一直在努力,终于得到了完整的工作解决方案,用于 php 中的 Google Drive V3。如下:

您可以阅读此要点以获得完整的代码并更好地理解: https://gist.github.com/KartikWatts/22dc9eb20980b5b4e041ddcaf04caf9e

首先添加@Hitu Bansal 的答案: 此代码工作正常:

$this->newPermission = new Google_Service_Drive_Permission();
$value=<YOUR EMAIL ADDRESS>;
$type="user";
$role="reader";
$this->newPermission->setEmailAddress($value);
$this->newPermission->setType($type);
$this->newPermission->setRole($role);
$this->newPermission->allowFileDiscovery;

try 
$res= $this->service->permissions->create($folder_id, $this->newPermission);
print_r($res);
catch (Exception $e) 
    print "An error occurred: " . $e->getMessage();

如果您想与任何人共享链接:您可以使用

    $type="anyone";
    $this->newPermission->setType($type);
    $this->newPermission->setRole($role);
    $this->newPermission->allowFileDiscovery;
    $this->newPermission->view;

注意:

在这种情况下,setEmailAddress() 应被删除。 重要提示:如果是'anyone',该文件夹肯定不会在您的个人驱动器中可见,但您仍然可以根据给定角色访问该文件夹并与之交互通过使用您已经知道的 folder_id 访问链接。因此,您可以通过以下方式访问该链接:https://drive.google.com/drive/u/5/folders/**folder_id** 现在可以公开访问。

为了更清楚地参考参数和描述,这真的很有帮助:https://developers.google.com/drive/api/v3/reference/permissions#methods

注意:在我个人看来,使用 Google Drive API 的更好方法是首先手动创建文件夹(如果工作流程允许的话),然后使用创建的文件夹 ID 上传文件文件夹。 切记,如果文件夹是手动创建的,需要先给Service Account email-id提供权限。

【讨论】:

【参考方案5】:

虽然权限问题是此问题的主要原因。在使用服务帐户上传文件夹或文件后,我所做的是指定父文件夹。如果您在没有父文件夹 ID 的情况下上传/创建文件夹/文件,则该对象的所有者将是您正在使用的服务帐户。 通过指定父 ID,它将使用继承的权限。 这是我在 php (google/apiclient) 中使用的代码

$driveFile = new Google\Service\Drive\DriveFile();
$driveFile->name = 'New Folder';
$driveFile->mimeType = 'application/vnd.google-apps.folder';
$driveFile->parents = ['123456789qwertyuiop'];
$result = $service->files->create($driveFile);

【讨论】:

以上是关于我看不到使用 php 在我的 Google Drive 中通过 api 创建的文件和文件夹的主要内容,如果未能解决你的问题,请参考以下文章

PHP Google App Engine YAML 找不到目录

在我的端点上看不到 Google Pub/Sub 推送通知

通过我的 php.ini 中的数据填充嵌入在我的网站上的 Google 表单。

React-native Google Drive如何获取文件和文件夹列表?

在 ionic 3 应用程序中找不到命名空间“google”

尝试在我的应用中集成 Google 登录时找不到“GoogleService-Info.plist”