英文:
GOOGLE_APPLICATION_CREDENTIALS can't be found
问题
目前必须将Google Cloud Platform服务集成到我的应用程序中,但是遇到了以下异常:
W/System.err: 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.
at com.google.auth.oauth2.DefaultCredentialsProvider.getDefaultCredentials(DefaultCredentialsProvider.java:134)
W/System.err: at com.google.auth.oauth2.GoogleCredentials.getApplicationDefault(GoogleCredentials.java:119)
at com.google.auth.oauth2.GoogleCredentials.getApplicationDefault(GoogleCredentials.java:91)
at com.google.api.gax.core.GoogleCredentialsProvider.getCredentials(GoogleCredentialsProvider.java:67)
at com.google.api.gax.rpc.ClientContext.create(ClientContext.java:135)
at com.google.cloud.speech.v1.stub.GrpcSpeechStub.create(GrpcSpeechStub.java:94)
at com.google.cloud.speech.v1.stub.SpeechStubSettings.createStub(SpeechStubSettings.java:131)
at com.google.cloud.speech.v1.SpeechClient.<init>(SpeechClient.java:144)
at com.google.cloud.speech.v1.SpeechClient.create(SpeechClient.java:126)
at com.google.cloud.speech.v1.SpeechClient.create(SpeechClient.java:118)
at com.dno.app.ui.TranscriptFragment$1.onClick(TranscriptFragment.java:72)
环境变量已设置:
.json文件在这里:
应用程序在此代码块(片段)中的authImplicit()处崩溃:
transcriptBtn = getActivity().findViewById(R.id.transcript_button);
transcriptBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try (SpeechClient speechClient = SpeechClient.create()) {
authImplicit(); // Google平台登录验证存在问题
// - 无法读取环境变量,因此无法访问.json文件。
// 要转录的音频文件路径
String fileName = getFile().getName();
// 将音频文件读入内存
Path path = Paths.get(fileName);
byte[] data = Files.readAllBytes(path);
ByteString audioBytes = ByteString.copyFrom(data);
// 构建同步识别请求
RecognitionConfig config =
RecognitionConfig.newBuilder()
.setEncoding(RecognitionConfig.AudioEncoding.FLAC)
.setSampleRateHertz(16000)
.setLanguageCode("en-US")
.build();
RecognitionAudio audio = RecognitionAudio.newBuilder().setContent(audioBytes).build();
// 对音频文件执行语音识别
RecognizeResponse response = speechClient.recognize(config, audio);
List<SpeechRecognitionResult> results = response.getResultsList();
for (SpeechRecognitionResult result : results) {
// 对于给定的语音块,可能会有几个备选的转录结果。这里只使用第一个(最可能的)。
SpeechRecognitionAlternative alternative = result.getAlternativesList().get(0);
System.out.printf("Transcription: %s%n", alternative.getTranscript());
}
} catch (IOException e) {
e.printStackTrace();
}
}
});
authImplicit()代码:
private void authImplicit() {
// 如果在构建客户端时没有指定凭据,客户端库将通过环境变量GOOGLE_APPLICATION_CREDENTIALS查找凭据。
Storage storage = StorageOptions.getDefaultInstance().getService();
System.out.println("Buckets:");
Page<Bucket> buckets = storage.list();
for (Bucket bucket : buckets.iterateAll()) {
System.out.println(bucket.toString());
}
}
我选择了一种Owner类型的服务帐户,因此不应缺少任何权限。
编辑(仍然不起作用):
我尝试了这个示例,但仍然不起作用:https://stackoverflow.com/questions/55496769/the-application-default-credentials-are-not-available?rq=1
编辑#2(在服务器端工作):
事实证明,Google目前不支持Android进行此任务。因此,我已将代码移到了ASP.NET后端,代码现在运行顺利。
感谢下面的帮助。
英文:
Currently have to integrate Google Cloud Platform services into my app but recieving the following exception:
**W/System.err: 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.
at com.google.auth.oauth2.DefaultCredentialsProvider.getDefaultCredentials(DefaultCredentialsProvider.java:134)
W/System.err: at com.google.auth.oauth2.GoogleCredentials.getApplicationDefault(GoogleCredentials.java:119)
at com.google.auth.oauth2.GoogleCredentials.getApplicationDefault(GoogleCredentials.java:91)
at com.google.api.gax.core.GoogleCredentialsProvider.getCredentials(GoogleCredentialsProvider.java:67)
at com.google.api.gax.rpc.ClientContext.create(ClientContext.java:135)
at com.google.cloud.speech.v1.stub.GrpcSpeechStub.create(GrpcSpeechStub.java:94)
at com.google.cloud.speech.v1.stub.SpeechStubSettings.createStub(SpeechStubSettings.java:131)
at com.google.cloud.speech.v1.SpeechClient.<init>(SpeechClient.java:144)
at com.google.cloud.speech.v1.SpeechClient.create(SpeechClient.java:126)
at com.google.cloud.speech.v1.SpeechClient.create(SpeechClient.java:118)
at com.dno.app.ui.TranscriptFragment$1.onClick(TranscriptFragment.java:72)**
Environment variable is set:
.json file is here:
the app crashes at authImplicit() in this code block (fragment):
transcriptBtn = getActivity().findViewById(R.id.transcript_button);
transcriptBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try (SpeechClient speechClient = SpeechClient.create()) {
authImplicit(); // issue with Google Platform Login Authentification
// - does not read the environment variable, and therefore cannot get access to the .json file.
// The path to the audio file to transcribe
String fileName = getFile().getName();
// Reads the audio file into memory
Path path = Paths.get(fileName);
byte[] data = Files.readAllBytes(path);
ByteString audioBytes = ByteString.copyFrom(data);
// Builds the sync recognize request
RecognitionConfig config =
RecognitionConfig.newBuilder()
.setEncoding(RecognitionConfig.AudioEncoding.FLAC)
.setSampleRateHertz(16000)
.setLanguageCode("en-US")
.build();
RecognitionAudio audio = RecognitionAudio.newBuilder().setContent(audioBytes).build();
// Performs speech recognition on the audio file
RecognizeResponse response = speechClient.recognize(config, audio);
List<SpeechRecognitionResult> results = response.getResultsList();
for (SpeechRecognitionResult result : results) {
// There can be several alternative transcripts for a given chunk of speech. Just use the
// first (most likely) one here.
SpeechRecognitionAlternative alternative = result.getAlternativesList().get(0);
System.out.printf("Transcription: %s%n", alternative.getTranscript());
}
} catch (IOException e) {
e.printStackTrace();
}
}
});
code for authImplicit():
private void authImplicit() {
// If you don't specify credentials when constructing the client, the client library will
// look for credentials via the environment variable GOOGLE_APPLICATION_CREDENTIALS.
Storage storage = StorageOptions.getDefaultInstance().getService();
System.out.println("Buckets:");
Page<Bucket> buckets = storage.list();
for (Bucket bucket : buckets.iterateAll()) {
System.out.println(bucket.toString());
}
}
I have selected a service account of the type, Owner, so I shouldn't be lacking any permissions.
EDIT (Still not working):
I tried using this example but it still doesn't work: https://stackoverflow.com/questions/55496769/the-application-default-credentials-are-not-available?rq=1
EDIT #2 (Working on server-side):
As it turns out, Google does not currently support Android for this task. Since this, I've moved the code to an ASP.NET back-end, and the code is now running smoothly.
Thank you for the assistance below.
答案1
得分: 2
我能理解你已经阅读了文档并按照这里的步骤实施了所有操作 - https://cloud.google.com/storage/docs/reference/libraries#windows
-
正如 @John Hanley 所提到的,你是否检查了打印环境变量?
-
这绝对不是与所有者相关的权限问题,因为异常消息如下所示:
java.io.IOException: 应用程序默认凭据不可用。如果在 Google 计算引擎中运行,它们是可用的。否则,必须定义环境变量 GOOGLE_APPLICATION_CREDENTIALS,指向定义凭据的文件。有关更多信息,请参见 https://developers.google.com/accounts/docs/application-default-credentials。
现在,为了解决这个问题,你想要只使用环境变量吗?还是其他方法也可以?
如果你接受其他方法,那么请看一下这段代码:
private void authImplicit() {
// 请提供这个 credentials.json 的确切文件名
Credentials credentials = GoogleCredentials
.fromStream(new FileInputStream("C:\\Users\\dbgno\\Keys\\credentials.json"));
Storage storage = StorageOptions.newBuilder().setCredentials(credentials)
.setProjectId("Some Project").build().getService();
System.out.println("Buckets:");
Page<Bucket> buckets = storage.list();
for (Bucket bucket : buckets.iterateAll()) {
System.out.println(bucket.toString());
}
}
编辑 1:朝向解决方案迈进
尝试这个,看看你能否读取你所提供的 JSON 文件。打印语句应该显示你打算进行身份验证的服务帐户。
public static Credential getDriveService(String fileLocation, String servAccAdmin)
throws IOException {
HttpTransport httpTransport = new NetHttpTransport();
JsonFactory jsonFactory = new JacksonFactory();
GoogleCredential googleCredential =
GoogleCredential.fromStream(new FileInputStream(fileLocation), httpTransport, jsonFactory)
.createScoped(SCOPES);
System.out.println("--------------- " + googleCredential.getServiceAccountId());
Credential credential = new GoogleCredential.Builder()
.setTransport(googleCredential.getTransport())
.setJsonFactory(googleCredential.getJsonFactory())
.setServiceAccountPrivateKeyId(googleCredential.getServiceAccountPrivateKeyId())
.setServiceAccountId(googleCredential.getServiceAccountId())
.setServiceAccountScopes(SCOPES)
.setServiceAccountPrivateKey(googleCredential.getServiceAccountPrivateKey())
.setServiceAccountUser(servAccAdmin)
.build();
return credential;
}
编辑 2:
由于我们看到一些凭据问题,我正在尝试查看我如何访问任何其他谷歌 API 服务,无论是驱动程序还是 Gmail,我们都会手动传递密钥文件并构建凭证,这些凭证应该用于后续的服务调用。现在尝试添加这些依赖项,这仅仅是为了通过与我们访问谷歌驱动程序/ Gmail 等相同的方式来排除故障。我们将知道谷歌云 API 是否能够构建凭据。
<dependency>
<groupId>com.google.http-client</groupId>
<artifactId>google-http-client</artifactId>
<version>${project.http.version}</version>
</dependency>
<dependency>
<groupId>com.google.http-client</groupId>
<artifactId>google-http-client-jackson2</artifactId>
<version>${project.http.version}</version>
</dependency>
<dependency>
<groupId>com.google.oauth-client</groupId>
<artifactId>google-oauth-client-jetty</artifactId>
<version>${project.oauth.version}</version>
</dependency>
英文:
I can understand you you've read the documentation and implemented all the steps stated here - https://cloud.google.com/storage/docs/reference/libraries#windows
-
As @John Hanley mentioned, did you check printing environmental variables ?
-
Its definitely not owner related permissions issue as the exception says
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.
Now, to solve this, do you want to do only using environmental variables ? or other approaches are fine ?
if you are ok with other approaches, then take a look at this code
private void authImplicit() {
//please give exact file name for this credentials.json
Credentials credentials = GoogleCredentials
.fromStream(new FileInputStream("C:\\Users\\dbgno\\Keys\\credentials.json"));
Storage storage = StorageOptions.newBuilder().setCredentials(credentials)
.setProjectId("Some Project").build().getService();
System.out.println("Buckets:");
Page<Bucket> buckets = storage.list();
for (Bucket bucket : buckets.iterateAll()) {
System.out.println(bucket.toString());
}
}
Edit 1: working towards solution
Try this and see if you can read the JSON file that you are giving as input. The print statement should show the service account using which you are aiming to authenticate
public static Credential getDriveService(String fileLocation, String servAccAdmin)
throws IOException {
HttpTransport httpTransport = new NetHttpTransport();
JsonFactory jsonFactory = new JacksonFactory();
GoogleCredential googleCredential =
GoogleCredential.fromStream(new FileInputStream(fileLocation), httpTransport, jsonFactory)
.createScoped(SCOPES);
System.out.println("--------------- " + googleCredential.getServiceAccountId());
Credential credential = new GoogleCredential.Builder()
.setTransport(googleCredential.getTransport())
.setJsonFactory(googleCredential.getJsonFactory())
.setServiceAccountPrivateKeyId(googleCredential.getServiceAccountPrivateKeyId())
.setServiceAccountId(googleCredential.getServiceAccountId()).setServiceAccountScopes(SCOPES)
.setServiceAccountPrivateKey(googleCredential.getServiceAccountPrivateKey())
.setServiceAccountUser(servAccAdmin).build();
return credential;
}
Edit 2:
As we are seeing some credential issue, I am trying to see the way I access any other google API service, may it be drive or gmail where we manually pass the key file and build credentials, and these credentials should be used in further service calls. Now try adding these dependencies, this is just to troubleshoot by using the same way that we access google drive/gmail and etc. We will get to know if google cloud api is able to build the credential or not
<dependency>
<groupId>com.google.http-client</groupId>
<artifactId>google-http-client</artifactId>
<version>${project.http.version}</version>
</dependency>
<dependency>
<groupId>com.google.http-client</groupId>
<artifactId>google-http-client-jackson2</artifactId>
<version>${project.http.version}</version>
</dependency>
<dependency>
<groupId>com.google.oauth-client</groupId>
<artifactId>google-oauth-client-jetty</artifactId>
<version>${project.oauth.version}</version>
</dependency>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论