Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gapi.client.init() promise fails silently if clientId/scope are provided #575

Open
jameshfisher opened this issue Nov 23, 2019 · 7 comments

Comments

@jameshfisher
Copy link

Steps to reproduce

Copy-paste this into index.html and open in a web app:

<!doctype html>
<html>
	<head>
		<link rel="manifest" href="/manifest.json">
	</head>
	<body>
    <script src="https://apis.google.com/js/auth2:client:platform.js?onload=initGapi" async defer></script>
    <script>
      const CLIENT_ID = '<CLIENT_ID>';
      const API_KEY = '<API_KEY>';
      const SCOPES = 'profile email https://www.googleapis.com/auth/calendar.readonly';
      const DISCOVERY_DOCS = ["https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest"];
      function initGapi() {
        console.log("initGapi");
        gapi.auth2.init({
          client_id: CLIENT_ID,
          scope: SCOPES,
          ux_mode: 'redirect',
          redirect_uri: `${window.location.protocol}//${window.location.hostname}${window.location.port?':'+window.location.port:''}/dashboard`,
        }).then(() => {
          console.log("auth2 inited");
          gapi.client.init({
            apiKey: API_KEY,
            discoveryDocs: DISCOVERY_DOCS,
            clientId: CLIENT_ID,
            scope: SCOPES
          }).then(() => {
            console.log("client inited");
          }).catch((err) => {
            console.error("error initing client", err);
          });
        }).catch((err) => {
          console.error("error initing auth2", err);
        })
      }
    </script>
	</body>
</html>

Expected behavior

Logs are

initGapi
auth2 inited
client inited

Actual behavior

Logs are

initGapi
auth2 inited

The client inited log line never appears. Crucially, neither does any error initing client log line. So the returned Promise is violating its promise to either call the then callback or the catch callback.

Cause

This behavior goes away if clientId: CLIENT_ID, scope: SCOPES is removed from the gapi.client.init call. When those keys are removed, we get the full expected log lines.

The docs for gapi.client.init say that:

If OAuth client ID and scope are provided, this function will load the gapi.auth2 module to perform OAuth.

So presumably, gapi.client.init notices that those keys are present, so tries to "load the gapi.auth2 module to perform OAuth". In my example, the gapi.auth2 module is already loaded. Under these conditions, gapi.client.init somehow forgets its duty to fulfil the returned promise.

@santhosh-rajashekar
Copy link

santhosh-rajashekar commented May 21, 2020

I faced the same issue and i followed the below alternative solution as a workaround.

` function initGapi() {
console.log(' window.gapi.init attempted ');

if (window.gapi != null && window.gapi.auth2 != null && window.gapi.auth2.getAuthInstance().isSignedIn.get()) {
  //just init the  window.gapi.client and do not wait for response as init API is not responding
  window.gapi.client
    .init({
      apiKey: API_KEY,
      clientId: CLIENT_ID,
      discoveryDocs: DISCOVERY_DOCS,
      scope: SCOPES,
    }).then((response) => {
      console.log("window.gapi.init responded positive");
      console.log(response);
    }, (error) => {
      console.log("window.gapi.init responded failue");
      console.log(error);
    });
  setTimeout(() => { method goes here to call the apis, in my case Google Drive APIS; }, 1000);
  return;
}

window.gapi.client
  .init({
    apiKey: API_KEY,
    clientId: CLIENT_ID,
    discoveryDocs: DISCOVERY_DOCS,
    scope: SCOPES,
  })
  .then(
    () => {
      console.log(' window.gapi.client is successful');
      window.gapi.auth2
        .getAuthInstance()
        .isSignedIn.listen(() => updateSigninStatus);

      // Handle the initial sign-in state. && inside the updateSigninStatus, will call the apis to perform opeartions in my case google drive apis to fetch files information
      updateSigninStatus(
        window.gapi.auth2.getAuthInstance().isSignedIn.get()
      );
    },
    (error) => {
      console.log(error);
    }
  );

}`

@avin-shum
Copy link

I also encounter this problem. If I set the Chrome F12 to 'offline', I can only find the below error in the console but neither onfulfilled() nor onrejected() is called.

GET https://apis.google.com/js/googleapis.proxy.js?onload=startup net::ERR_INTERNET_DISCONNECTED

@grgsolymosi
Copy link

@jameshfisher Here is the same.

@jameshfisher
Copy link
Author

FYI: my eventual approach was to abandon gapi and use traditional server side SSO. I found gapi to be too full of bugs and complexities and weird behavior.

@insomniac807
Copy link

This Bug seems to be still present

@sanchitbansal10
Copy link

facing the same issue

@adamg-wix
Copy link

Wrap it with a try catch. the onError callback only gets invoked when there's an error during invokation and not when there's an error with a pre-condition.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants
@jameshfisher @grgsolymosi @santhosh-rajashekar @sanchitbansal10 @insomniac807 @avin-shum @adamg-wix and others