Электронные таблицы не найдены при использовании AppIdentityService для аутентификации

Я могу успешно аутентифицировать свое приложение движка приложения, используя AppIdentityService. Однако, когда я выполняю SpreadsheetService.getEntries, я не получаю записей.

Вот мой код:

SpreadsheetService service = new SpreadsheetService("Spreadsheet editing");
String[] SCOPESArray = { "https://spreadsheets.google.com/feeds" };
final List SCOPES = Arrays.asList(SCOPESArray);
AppIdentityService appIdentity = AppIdentityServiceFactory.getAppIdentityService();
AppIdentityService.GetAccessTokenResult accessToken = appIdentity.getAccessToken(SCOPES);

Credential creds = new Credential(BearerToken.authorizationHeaderAccessMethod());
creds.setAccessToken(accessToken.getAccessToken());    
service.setOAuth2Credentials(creds);

SpreadsheetFeed feed = service.getFeed(new URL("https://spreadsheets.google.com/feeds/spreadsheets/private/full"), SpreadsheetFeed.class);

List spreadsheets = feed.getEntries();

На данный момент электронные таблицы — это пустой список.

Я поделился электронной таблицей со своим приложением, введя адрес электронной почты учетной записи службы в поле «Поделиться» электронной таблицы — это электронная почта в форме: [email protected].

Я неправильно понял разрешения здесь? Разве «совместного использования» электронной таблицы с учетной записью службы недостаточно, чтобы учетная запись службы «увидела» электронную таблицу?


person Dan Gravell    schedule 29.05.2015    source источник


Ответы (2)


На данный момент я считаю, что AppIdentity не поддерживается при обновлении с помощью API Таблиц из Google App Engine.

Кажется возможным пройти аутентификацию, но список SpreadsheetEntry всегда пуст.

Вместо этого используйте учетную запись службы из Google App Engine, указав учетные данные в экземпляре GoogleCredential:

GoogleCredential creds = new GoogleCredential.Builder()
    .setTransport(GoogleNetHttpTransport.newTrustedTransport())
    .setJsonFactory(JacksonFactory.getDefaultInstance())
    .setServiceAccountId(serviceAccountEmailAddress)
    .setServiceAccountPrivateKeyFromP12File(p12FileFromCredentials)
    .setServiceAccountScopes(SCOPES)
    .build();


service.setOAuth2Credentials(creds);
person Dan Gravell    schedule 01.06.2015

Я обнаружил, что совместное использование не очень хорошо работает в Документах Google, т. Е. Папка «Доступные мне» была довольно неполной. Кажется, с Drive это улучшилось, но API электронных таблиц устарел...

Что я делаю, так это делюсь папками, содержащими электронные таблицы, с учетной записью службы App Engine и использую Drive API для перечисления электронных таблиц в этих папках. Доступ к папкам осуществляется по их ключу. Это позволяет мне настраивать разные папки для модульного тестирования, тестирования и производства.

Вот пример кода для получения электронных таблиц из папки:

public enum MimeType { //
  SPREADSHEET ("application/vnd.google-apps.spreadsheet"),
  EXCEL ("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");

  private String type;
  MimeType(String type) {this.type = type;}

  public String getType() {
    return type;
  }
}

/**
 * Get a list of files of a given type from a folder 
 * 
 * @param folderId The Id of the folder
 * @param type The mime type of the files
 * @return a {@link FileList} containing the desired files
 * @throws IOException
 */
public FileList getFolderItems(String folderId, MimeType type) throws IOException {
    QueryBuilder query = new QueryBuilder();
    query.addParent(folderId).setMimeType(type);
    FileList list = drive.files().list().setQ(query.getQuery()).execute();
    return list;
}

Затем вы можете использовать File.getId() для получения ключа файла для использования с API электронных таблиц.

Кроме того, я не рекомендую использовать API электронных таблиц из App Engine. API постоянно сталкивается с тайм-аутами и другими исключениями при вызове из GAE. Мне пришлось перенести обработку в задачу, поставленную в очередь, которая, к сожалению, не имеет более длительных тайм-аутов URLFetch, как было обещано (см. issue 10470), но, по крайней мере, запросы не отменяются.

Я написал оболочку для большинства вызовов API электронных таблиц, чтобы повторить вызов при получении исключения. И я постоянно добавляю больше оберток.

person Alex R    schedule 30.05.2015
comment
Спасибо, но я так и не смог заставить это работать с AppIdentity. В конце концов, сработало переключение на использование именованной учетной записи службы с GoogleCredential. - person Dan Gravell; 01.06.2015
comment
Я использую ту же последовательность команд для работы с API электронных таблиц с AppIdentity. Вы пробовали какую-либо другую команду, используя данный ключ файла в API? Подключение к моему Диску было создано с использованием других учетных данных с использованием AppIdentityCredential.Builder - person Alex R; 01.06.2015
comment
Привет, Алекс. Спасибо за информацию, действительно лучше использовать Drive API, где это возможно. Один вопрос; как получить электронную таблицу с помощью File.getId()? У вас есть пример? С уважением, Роланд - person Roland Beuker; 04.03.2016
comment
@Roland Beuker Я использую urlFactory.getWorksheetFeedUrl(file.getId(), "private", "full") (или любой другой конструктор URL-адресов каналов). file.getId() возвращает ключ электронной таблицы - person Alex R; 04.03.2016
comment
@Alex После некоторой отладки я обнаружил: String lSpreadsheetFileId = pSpreadsheetFile.getId(); String lSpreadsheetUrlString = String.format("https://spreadsheets.google.com/feeds/spreadsheets/%s", lSpreadsheetFileId); URL lSpreadsheetUrl = new URL(lSpreadsheetUrlString); SpreadsheetEntry lSpreadsheetEntry = = mSpreadsheetService.getEntry(lSpreadsheetUrl, SpreadsheetEntry.class); Но как вы используете свой WorksheetFeedUrl для получения SpreadsheetEntry? - person Roland Beuker; 04.03.2016
comment
@Roland Beuker Я не знаю; что мне делать с SpreadhsheetEntry? Все, что он может сделать, это дать мне рабочие листы. Который я получаю из WorksheetFeed. - person Alex R; 07.03.2016
comment
Я создал библиотеку с возможностью работы с файлами SpreadsheetService и GoogleDrive. В приведенном выше решении единственная разница заключается в том, как я получаю свой SpreadsheetEntry. Из этого класса верхнего уровня весь код является общим... Мне также нравится SpreadsheetEntry, поскольку он моделирует одну электронную таблицу, какой она на самом деле является в реальном мире. - person Roland Beuker; 07.03.2016
comment
@Roland Beuker Задайте вопрос, и я могу добавить пример кода. - person Alex R; 07.03.2016
comment
@Alex, спасибо, вот ссылка на мой вопрос: stackoverflow.com/ вопросы/35863845/ - person Roland Beuker; 08.03.2016