I have the following Java code to try and get a single metric from GA4 using the GA4 Java bindings / classes:
String propertyId = "123123123";
GoogleCredentials gc = ServiceAccountCredentials.fromStream(this.getClass().getResourceAsStream("/client_secrets.json"))
.createScoped(Collections.singletonList(StorageScopes.DEVSTORAGE_FULL_CONTROL));
BetaAnalyticsDataSettings betaAnalyticsDataSettings = BetaAnalyticsDataSettings.newBuilder().setCredentialsProvider(FixedCredentialsProvider.create(gc)).build();
BetaAnalyticsDataClient betaAnalyticsDataClient = BetaAnalyticsDataClient.create(betaAnalyticsDataSettings);
RunReportRequest request = RunReportRequest.newBuilder().setProperty("properties/" + propertyId).
addMetrics(Metric.newBuilder().setName("active7DayUsers")).
addDateRanges(DateRange.newBuilder().
setStartDate("2023-07-31").setEndDate("today")).build();
RunReportResponse response = betaAnalyticsDataClient.runReport(request);
This results in an exception in the RunReportResponse generation, e. g.
com.google.api.gax.rpc.PermissionDeniedException: io.grpc.StatusRuntimeException: PERMISSION_DENIED: Request had insufficient authentication scopes
How can I get sufficient authentication scope?
I have so far
- Confirmed, reconfirmed and confirmed again my PropertID passed in code is for the correct GA4 property.
- Confirmed, reconfirmed and confirmed again that the GA4 account in which this PropertyID resides is in fact the account implied by my client_secrets.json downloaded from the GA4 web interface, via the Serivce Account implied in the client_secrets.json file, via the client_email field.
- Confirmed, reconfirmed and confirmed again that the GA4 Service Account implied by my client_secrets.json file is, in fact, the GA4 service account associated with this Account and Property I am referencing, in the GA4 web interface.
- Confirmed, reconfirmed and confirmed again that the Account referenced and Property referenced in code above have full administrator privileges active in the GA4 web interface.
Any ideas or pointers?
I've worked through every GUI option I can find, I have full admin permissions set for the GA4 Account and Property, and using the GA4 GUI I can SEE the properties are there, data is accumulating, etc. - everything is working EXCEPT the API.
The issue is incredibly common and I've worked through several posts about this, but there is simply no resolution.
I've also tried downgrading each permission for both the Account and Property, and upgrading them in all possible combinations, keep getting
com.google.api.gax.rpc.PermissionDeniedException: io.grpc.StatusRuntimeException: PERMISSION_DENIED: Request had insufficient authentication scope
What am I doing wrong? Is there something wrong with the code above?
Thanks


This is now solved thanks to Shila Mosammami.
Turns out, if I use this way to get a credential to access my GA4 analytics property via the service account JSON generated file per the official procedure outlined in Google's documentation for the GA4 Java API:
I -always- get
HOWEVER
As kindly suggested by Shila Mossasami, if I use this to get the required GA4 credentials off the service account JSON file per the official procedure outlined in Google's documentation for the GA4 Java API:
it all just works and the above error
is no longer present.
And I can now pull statistics via the GA4 API - at last!
Here's the complete working code integrating Shila's suggestion:
"response" then contains my response data as required.
Note that I use NetBeans 11 for this, so "client_secrets.json" is located in
in the NetBeans 11 Project Tree Gui at the left of the NetBeans 11 interface.
If "client_secrets.json" is placed there in NetBeans 11, the file can be refereced via
in the Java code (this took me several hours to figure out, hopefully this saves someone some effort.)
Thanks again Shila! You're the hero of the day.