Google Dialogflow: учетные данные приложения по умолчанию недоступны

Привет! У меня проблема с библиотекой Java SDK для Google Cloud.

Мне нужно запросить API-интерфейс Dialogflow V2, и я использую этот SDK ( https://github.com/GoogleCloudPlatform/google-cloud-java/tree/master)

Я следовал инструкциям, чтобы установить GOOGLE_APPLICATION_CREDENTIALS в качестве переменной среды.

Я сделал несколько попыток (я использую Mac):

export GOOGLE_APPLICATION_CREDENTIALS=path/to/my.json

не работает

сдачи

export GOOGLE_APPLICATION_CREDENTIALS=path/to/my.json

в.bash_profile

не работает

В моем коде Java:

System.setProperty("GOOGLE_APPLICATION_CREDENTIALS", "/path/to/my.json");
GoogleCredential credential = GoogleCredential.getApplicationDefault();

не работает

String jsonPath = "/path/to/my.json";
GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream(jsonPath));
Storage storage = StorageOptions.newBuilder().setCredentials(credentials).build().getService();

не работает

поместить GOOGLE_APPLICATION_CREDENTIALS в качестве переменной среды в Eclipse с помощью "Maven build > Environment > New variable" и перезапустить IDE

не работает

Всегда возникает одна и та же ошибка:

An error occurred during Dialogflow http request: The Application Default Credentials are not available. They are available if running in Google Compute Engine. Otherwise, the environment variable GOOGLE_APPLICATION_CREDENTIALS must be defined pointing to a file defining the credentials. See https://developers.google.com/accounts/docs/application-default-credentials for more information.
java.io.IOException: The Application Default Credentials are not available. They are available if running in Google Compute Engine. Otherwise, the environment variable GOOGLE_APPLICATION_CREDENTIALS must be defined pointing to a file defining the credentials. See https://developers.google.com/accounts/docs/application-default-credentials for more information

На самом деле я не могу понять, что не так.

Это фрагмент кода для запроса Dialogflow, который никогда не был достигнут из-за вышеуказанной ошибки:

SessionsClient sessionsClient = SessionsClient.create();
SessionName session = SessionName.of("my-project-id", sessionId);
InputStream stream = new ByteArrayInputStream(requestBody.getBytes(StandardCharsets.UTF_8));
QueryInput queryInput = QueryInput.newBuilder().build().parseFrom(stream);
DetectIntentResponse response = sessionsClient.detectIntent(session, queryInput);  

Исключение поднято на

SessionsClient sessionsClient = SessionsClient.create();

Заранее спасибо.

3 ответа

Решение состоит в том, чтобы установить GOOGLE_APPLICATION_CREDENTIALS в качестве переменной среды для Сервера приложений.

Попробуйте получить учетные данные по умолчанию, используя команду входа

gcloud auth application-default login

В отличие от упомянутого в вопросе, у меня есть "учетные данные", работающие при условии, что таким образом

Storage storage = StorageOptions.newBuilder().setCredentials(credentials).build().getService();

Но тот же подход с FirestoreOptions не удалось с указанной ошибкой "Учетные данные приложения по умолчанию недоступны".

Примечание. Я не хочу настраивать свое приложение с помощью переменной среды и предпочитаю делать это в коде. Еще одна причина для этого - мне нужно несколько разных соединений из одного приложения.

После отладки в коде Google я обнаружил, что они не используют предоставленные учетные данные, они скорее вызывают getCredentialsProvider() по предоставленным опциям. Я думаю, что это ошибка в их реализации, но обходной путь довольно прост:

  1. Создать свой CredentialsProvider
  2. Установите его в FirestoreOptions

Фиктивный образец:

public static class MyCredentialsProvider implements CredentialsProvider {
    GoogleCredentials credentials;

    public MyCredentialsProvider(GoogleCredentials credentials) {
        this.credentials = credentials;
    }

    @Override
    public Credentials getCredentials() throws IOException {
        return credentials;
    }
}

...

FirestoreOptions.Builder builder = FirestoreOptions.newBuilder()
        .setProjectId(serviceAccount.project_id)
        .setCredentialsProvider(new MyCredentialsProvider(credentials));
Другие вопросы по тегам