I am working with Google Analytics API. My code is working locally. But it is not working on the Ubuntu Server instance. I have checked and done the following steps correctly:
- ADC is signed in using
gcloud auth login. I received a token and browser and signed in successfully. - The key file is accessible. I have tried
console.log(keyFileData)and it is coming correct. - The service account is configured successfully.
- Analytics Access has been given view access to the Service account email.
--- Client library initialization ---
private readonly analyticsDataClient = new BetaAnalyticsDataClient();
--- My configuration in my NestJS service File constructor ---
const keyFileContents = fs.readFileSync('./g4-client.json', 'utf8');
try {
const keyFileData = JSON.parse(keyFileContents);
// Create a Google Auth client using the key data
const auth = new google.auth.GoogleAuth({
credentials: keyFileData, // Pass the entire key object
scopes: 'https://www.googleapis.com/auth/analytics.readonly',
});
// Create a Google Analytics Reporting API client
this.analytics = google.analyticsreporting({
version: 'v4',
auth: auth,
});
// Use the 'analytics' client for API requests
} catch (error) {
console.error('Error parsing JSON key file:', error);
}
--- My code where I am trying to call the API ----
try {
const [response] = await this.analyticsDataClient.runReport({
property: `properties/12345678`,
dateRanges: [
{
// Cast the DateRange object to `any` to allow the interval property to be set.
startDate: '30daysAgo',
endDate: 'today',
},
{
startDate: '7daysAgo',
endDate: 'today',
}
],
dimensions: [
{
name: 'city',
},
],
metrics: [
{
name: 'activeUsers',
},
],
limit: '7',
orderBys: [
{
desc: true,
metric: {
metricName: 'activeUsers',
},
}
],
dimensionFilter: {
filter: {
fieldName: 'pagePath',
stringFilter: {
matchType: 'EXACT',
value: productHandle
}
}
},
});
const weeklyData = [];
const monthlyData = [];
response.rows.forEach((row) => {
const dimensionValues = row.dimensionValues;
const metricValue = row.metricValues[0].value;
// Determine if it's weekly or monthly data based on dimensionValues[1].value
const dateRange = dimensionValues[1].value;
// Create an object to store the data
const dataItem = {
city: dimensionValues[0].value,
metricValue: metricValue,
};
// console.log(dimensionValues, metricValue, dateRange, dataItem);
// Push the data into the respective arrays
if (dateRange === 'date_range_0') {
monthlyData.push(dataItem);
} else if (dateRange === 'date_range_1') {
weeklyData.push(dataItem);
}
});
return { weeklyData, monthlyData }
} catch (error) {
console.error('Error running the report:', error);
}
--- Error being encountered -----------
Error running the report: Error: 7 PERMISSION_DENIED: Request had insufficient authentication scopes.
4|api.xxx.com | at callErrorFromStatus (/var/www/api.xxx.com/node_modules/@grpc/grpc-js/src/call.ts:82:17)
4|api.xxx.com | at Object.onReceiveStatus (/var/www/api.xxx.com/node_modules/@grpc/grpc-js/src/client.ts:360:55)
4|api.xxx.com | at Object.onReceiveStatus (/var/www/api.xxx.com/node_modules/@grpc/grpc-js/src/client-interceptors.ts:458:34)
4|api.xxx.com | at Object.onReceiveStatus (/var/www/api.xxx.com/node_modules/@grpc/grpc-js/src/client-interceptors.ts:419:48)
4|api.xxx.com | at /var/www/api.xxx.com/node_modules/@grpc/grpc-js/src/resolving-call.ts:132:24
4|api.xxx.com | at processTicksAndRejections (node:internal/process/task_queues:77:11)
4|api.xxx.com | for call at
4|api.xxx.com | at ServiceClientImpl.makeUnaryRequest (/var/www/api.xxx.com/node_modules/@grpc/grpc-js/src/client.ts:325:42)
4|api.xxx.com | at ServiceClientImpl.<anonymous> (/var/www/api.xxx.com/node_modules/@grpc/grpc-js/src/make-client.ts:189:15)
4|api.xxx.com | at /var/www/api.xxx.com/node_modules/@google-analytics/data/build/src/v1beta/beta_analytics_data_client.js:190:29
4|api.xxx.com | at /var/www/api.xxx.com/node_modules/google-gax/build/src/normalCalls/timeout.js:44:16
4|api.xxx.com | at OngoingCallPromise.call (/var/www/api.xxx.com/node_modules/google-gax/build/src/call.js:67:27)
4|api.xxx.com | at NormalApiCaller.call (/var/www/api.xxx.com/node_modules/google-gax/build/src/normalCalls/normalApiCaller.js:34:19)
4|api.xxx.com | at /var/www/api.xxx.com/node_modules/google-gax/build/src/createApiCall.js:84:30
4|api.xxx.com | at processTicksAndRejections (node:internal/process/task_queues:95:5) {
4|api.xxx.com | code: 7,
4|api.xxx.com | details: 'Request had insufficient authentication scopes.',
4|api.xxx.com | metadata: Metadata {
4|api.xxx.com | internalRepr: Map(4) {
4|api.xxx.com | 'endpoint-load-metrics-bin' => [Array],
4|api.xxx.com | 'grpc-server-stats-bin' => [Array],
4|api.xxx.com | 'google.rpc.errorinfo-bin' => [Array],
4|api.xxx.com | 'grpc-status-details-bin' => [Array]
4|api.xxx.com | },
4|api.xxx.com | options: {}
4|api.xxx.com | },
4|api.xxx.com | statusDetails: [
4|api.xxx.com | ErrorInfo {
4|api.xxx.com | metadata: [Object],
4|api.xxx.com | reason: 'ACCESS_TOKEN_SCOPE_INSUFFICIENT',
4|api.xxx.com | domain: 'googleapis.com'
4|api.xxx.com | }
4|api.xxx.com | ],
4|api.xxx.com | reason: 'ACCESS_TOKEN_SCOPE_INSUFFICIENT',
4|api.xxx.com | domain: 'googleapis.com',
4|api.xxx.com | errorInfoMetadata: {
4|api.xxx.com | service: 'analyticsdata.googleapis.com',
4|api.xxx.com | method: 'google.analytics.data.v1beta.BetaAnalyticsData.RunReport'
4|api.xxx.com | }
4|api.xxx.com | }
4|api.xxx.com | undefined
4|api.xxx.com | Error fetching city-wise data: TypeError: Cannot read properties of undefined (reading 'weeklyData')
4|api.xxx.com | at AnalyticsResolver.fetchCityWiseData (/var/www/api.xxx.com/src/analytics/analytics.resolver.ts:42:35)
4|api.xxx.com | at target (/var/www/api.xxx.com/node_modules/@nestjs/core/helpers/external-context-creator.js:74:28)
4|api.xxx.com | at Object.fetchCityWiseData (/var/www/api.xxx.com/node_modules/@nestjs/core/helpers/external-proxy.js:9:24)
4|api.xxx.com | [Nest] 20957 - 10/12/2023, 8:48:08 AM ERROR [ExceptionsHandler] Error fetching city-wise data
4|api.xxx.com | Error: Error fetching city-wise data
4|api.xxx.com | at AnalyticsResolver.fetchCityWiseData (/var/www/api.xxx.com/src/analytics/analytics.resolver.ts:47:13)
4|api.xxx.com | at target (/var/www/api.xxx.com/node_modules/@nestjs/core/helpers/external-context-creator.js:74:28)
4|api.xxx.com | at Object.fetchCityWiseData (/var/www/api.xxx.com/node_modules/@nestjs/core/helpers/external-proxy.js:9:24)
4|api.xxx.com | Error running the report: Error: 7 PERMISSION_DENIED: Request had insufficient authentication scopes.
4|api.xxx.com | at callErrorFromStatus (/var/www/api.xxx.com/node_modules/@grpc/grpc-js/src/call.ts:82:17)
4|api.xxx.com | at Object.onReceiveStatus (/var/www/api.xxx.com/node_modules/@grpc/grpc-js/src/client.ts:360:55)
4|api.xxx.com | at Object.onReceiveStatus (/var/www/api.xxx.com/node_modules/@grpc/grpc-js/src/client-interceptors.ts:458:34)
4|api.xxx.com | at Object.onReceiveStatus (/var/www/api.xxx.com/node_modules/@grpc/grpc-js/src/client-interceptors.ts:419:48)
4|api.xxx.com | at /var/www/api.xxx.com/node_modules/@grpc/grpc-js/src/resolving-call.ts:132:24
4|api.xxx.com | at processTicksAndRejections (node:internal/process/task_queues:77:11)
4|api.xxx.com | for call at
4|api.xxx.com | at ServiceClientImpl.makeUnaryRequest (/var/www/api.xxx.com/node_modules/@grpc/grpc-js/src/client.ts:325:42)
4|api.xxx.com | at ServiceClientImpl.<anonymous> (/var/www/api.xxx.com/node_modules/@grpc/grpc-js/src/make-client.ts:189:15)
4|api.xxx.com | at /var/www/api.xxx.com/node_modules/@google-analytics/data/build/src/v1beta/beta_analytics_data_client.js:190:29
4|api.xxx.com | at /var/www/api.xxx.com/node_modules/google-gax/build/src/normalCalls/timeout.js:44:16
4|api.xxx.com | at OngoingCallPromise.call (/var/www/api.xxx.com/node_modules/google-gax/build/src/call.js:67:27)
4|api.xxx.com | at NormalApiCaller.call (/var/www/api.xxx.com/node_modules/google-gax/build/src/normalCalls/normalApiCaller.js:34:19)
4|api.xxx.com | at /var/www/api.xxx.com/node_modules/google-gax/build/src/createApiCall.js:84:30
4|api.xxx.com | at processTicksAndRejections (node:internal/process/task_queues:95:5) {
4|api.xxx.com | code: 7,
4|api.xxx.com | details: 'Request had insufficient authentication scopes.',
4|api.xxx.com | metadata: Metadata {
4|api.xxx.com | internalRepr: Map(4) {
4|api.xxx.com | 'endpoint-load-metrics-bin' => [Array],
4|api.xxx.com | 'grpc-server-stats-bin' => [Array],
4|api.xxx.com | 'google.rpc.errorinfo-bin' => [Array],
4|api.xxx.com | 'grpc-status-details-bin' => [Array]
4|api.xxx.com | },
4|api.xxx.com | options: {}
4|api.xxx.com | },
4|api.xxx.com | statusDetails: [
4|api.xxx.com | ErrorInfo {
4|api.xxx.com | metadata: [Object],
4|api.xxx.com | reason: 'ACCESS_TOKEN_SCOPE_INSUFFICIENT',
4|api.xxx.com | domain: 'googleapis.com'
4|api.xxx.com | }
4|api.xxx.com | ],
4|api.xxx.com | reason: 'ACCESS_TOKEN_SCOPE_INSUFFICIENT',
4|api.xxx.com | domain: 'googleapis.com',
4|api.xxx.com | errorInfoMetadata: {
4|api.xxx.com | service: 'analyticsdata.googleapis.com',
4|api.xxx.com | method: 'google.analytics.data.v1beta.BetaAnalyticsData.RunReport'
4|api.xxx.com | }
4|api.xxx.com | }
4|api.xxx.com | Error fetching city-wise data: TypeError: Cannot read properties of undefined (reading 'weeklyData')
4|api.xxx.com | at AnalyticsResolver.fetchCountryWiseData (/var/www/api.xxx.com/src/analytics/analytics.resolver.ts:59:35)
4|api.xxx.com | at target (/var/www/api.xxx.com/node_modules/@nestjs/core/helpers/external-context-creator.js:74:28)
4|api.xxx.com | at Object.fetchCountryWiseData (/var/www/api.xxx.com/node_modules/@nestjs/core/helpers/external-proxy.js:9:24)
4|api.xxx.com | [Nest] 20957 - 10/12/2023, 8:48:08 AM ERROR [ExceptionsHandler] Error fetching city-wise data
4|api.xxx.com | Error: Error fetching city-wise data
4|api.xxx.com | at AnalyticsResolver.fetchCountryWiseData (/var/www/api.xxx.com/src/analytics/analytics.resolver.ts:64:13)
4|api.xxx.com | at target (/var/www/api.xxx.com/node_modules/@nestjs/core/helpers/external-context-creator.js:74:28)
4|api.xxx.com | at Object.fetchCountryWiseData (/var/www/api.xxx.com/node_modules/@nestjs/core/helpers/external-proxy.js:9:24)
I don't know what to do. What details should I check?
