I'm trying to implement Google Analytics Graphs via their Javascript API, as the example on their site link.
But I keep getting "401 Invalid Credentials" each time I try to execute gapi.analytics.googleCharts.DataChart
I'm getting the access token server side (C#) using the following code with data from the JSON generated for the Service Account
var cred = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(clientId)
{
Scopes = new[] { AnalyticsReportingService.Scope.AnalyticsReadonly },
User = clientEmail,
ProjectId = "projectID"
}.FromPrivateKey(privateKey));
var token = cred.GetAccessTokenForRequestAsync(authURI);
token.Wait();
var result = token.Result;
return result;
or (using the full json string, see Note too)
GoogleCredential cred;
var gCred = GoogleCredential.FromJson(json).UnderlyingCredential as
ServiceAccountCredential;
var token = gCred.GetAccessTokenForRequestAsync("https://accounts.google.com/o/oauth2/auth");
return token.Result;
While on the client side
gapi.analytics.auth.authorize({
'serverAuth': {
'access_token': '{{ ACCESS_TOKEN_FROM_SERVICE_ACCOUNT }}'
}
});
goes through and using gapi.analytics.auth.isAuthorized() returns true using any of the server side functions but it fails when trying to call
var dataChart1 = new gapi.analytics.googleCharts.DataChart(queryJson);
dataChart1.execute();
returns 401 "Invalid Credentials", the server side query returns values just fine so I think the user permissions is not the issue
NOTE: Using the same code as the second one (generating the credential using the json string without casting as a ServiceAccountCredential) I can get data from the API server side
cred = gCred.CreateScoped(scopes);
using (var reportingService = new AnalyticsReportingService(new BaseClientService.Initializer
{
HttpClientInitializer = cred
}))
...
var getReportsRequest = new GetReportsRequest
{
ReportRequests = new List<ReportRequest> { reportRequest }
};
var batchRequest = reportingService.Reports.BatchGet(getReportsRequest);
var response = batchRequest.Execute(); //This returns a response object with all the data I need
If anyone has the same issue:
You need to use GoogleCredential.GetApplicationDefault() to create the Credential object, in the case of Analytics you should get something like this
var credential = GoogleCredential.GetApplicationDefault().CreateScoped(AnalyticsReportingService.Scope.AnalyticsReadonly);
This will get the json file from the Environment Variables on Windows, so you need to set GOOGLE_APPLICATION_CREDENTIALS with the path to the json as a System Variable.
Initialize the service and set the service variable
using (var reportingService = new AnalyticsReportingService(new BaseClientService.Initializer { HttpClientInitializer = credential }))
{
var serviceCredential = cred.UnderlyingCredential as ServiceAccountCredential;
}