I'm attempting to authenticate users with their google account using the implicit flow in order to retrieve that user's profile information, including:
- Phone number
- Organizational information (i.e. Company Name)
const apiKey = 'XXXXXX';
const clientId = 'XXXXXX';
const scopes = 'profile';
//const scopes = 'profile https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/user.phonenumbers.read';
let client;
let token;
let peopleApiDiscovery;
const discoveryDocs = ["https://people.googleapis.com/$discovery/rest?version=v1"];
let tokenClient;
let access_token;
const gapiLoad = async () => {
let clientResponse = await new Promise((resolve, error) => gapi.load('client', resolve));
console.log(`Load gapi.`);
}
const gisInit = async () => {
tokenClient = google.accounts.oauth2.initTokenClient({
client_id: clientId,
scope: scopes,
callback: async (tokenResponse) => {
console.log(`Token response:`, tokenResponse);
access_token = tokenResponse.access_token;
console.log(`Finished requesting access.`);
loadApis();
await loadUserInfo();
},
});
console.log(`Loaded token client.`);
await gapiLoad();
await getToken();
}
gisInit();
async function loadApis() {
let loader = [];
loader.push(gapi.client.load('https://www.googleapis.com/discovery/v1/apis/people/v1/rest'));
await Promise.all(loader);
console.log('Finished loading APIs.');
}
async function loadUserInfo() {
console.log(`Loading user info.`);
const response = gapi.client.oauth2.userinfo.get();
console.log(`Loaded user info: `, response.json.toString());
}
async function getToken() {
await tokenClient.requestAccessToken();
}
Everything seems to work fine until the call to userinfo.get(). I receive the exception:
Error: arrayForEach was called with a non array value
It appears that there are parameters necessary for the get method, but I can't find any documentation of them.
Here are the associated script elements:
<script src="https://accounts.google.com/gsi/client" async defer></script>
<script src="https://apis.google.com/js/api.js" async defer></script>
I've begun looking at trying to debug the obfuscated methods (which is difficult), but I get the sense that I may be doing something else wrong that I can't seem to find or figure out documentation for. Any assistance is appreciated.
In case this is coming from the response handling part of your code (as commented by EspressoCode, and since I do not see anything in
google/google-api-javascript-client), try first to inspect the exact response you are receiving from thegapi.client.oauth2.userinfo.get()API call.You might be getting an object instead of an array.
And update your
loadUserInfofunction to correctly handle potential errors and inspect the response structure. For instance, you can log the raw response to console before trying to accessresponse.json.toString():You can also try and pass the parameters explicitly:
Make sure that the People API is loaded and initialized before making the above API calls, and that the necessary scopes are included in your OAuth 2.0 request to grant the necessary permissions.