2

I get error:

Uncaught TypeError: Cannot read property 'signOut' of undefined

On this line: auth2.signOut()

I do NOT have the google signin button on the page below. I also tried executing function signOutGoogle, but that too results in an error.

Top of page my page in <head>:

<meta name="google-signin-scope" content="profile email">
<meta name="google-signin-client_id" content="MYAPPIDPLACEHOLDERWHICHIFILLEDOUT.apps.googleusercontent.com">

Before </body> tag I have:

<script src="https://apis.google.com/js/platform.js?onload=onLoad" async defer></script>

JavaScript code:

function onLoad() {
    console.error('onLoad executed.');
    var auth2;
    gapi.load('auth2', function () {
        auth2 = gapi.auth2.init({
           client_id: 'MYAPPIDPLACEHOLDERWHICHIFILLEDOUT.apps.googleusercontent.com'
        });
        auth2 = gapi.auth2.getAuthInstance();
    });  
           
    //check if url contains ?signout=true
    var url = window.location.href;
    if (url.toString().indexOf('?signout=true') != -1) {
        console.error('param found');

        auth2.signOut().then(function () {
            console.error('User signed out');
        });
    }
}

UPDATE 1

enter image description here

For some reason ga is called (which I don't do explicitly myself) and failing, what's happening here?

I already checked here:

UPDATE 2

Now I'm getting error

Uncaught Error: ia

enter image description here

UPDATE 3

I tried removing calling noload from the script call and then add it to document.ready to then call signout function, but then even with @Vishal's code the API is not yet available:

<script src="https://apis.google.com/js/platform.js"></script></body>

And:

    $(document).ready(function () {
        var url = window.location.href;
        if (url.toString().indexOf('?signout=true') != -1) {
            console.error('onLoad executed.');
            var auth2;
            gapi.load('auth2', function () {
                auth2 = gapi.auth2.init({
                    client_id: 'MYAPPIDPLACEHOLDERWHICHIFILLEDOUT.apps.googleusercontent.com'
                }).then(() => {
                    auth2 = gapi.auth2.getAuthInstance();
                    auth2.signOut().then(function () {
                        console.error('User signed out');
                    });
                }).catch(err => {
                    console.log(err);
                });
            });
        }
    });
Adam
  • 6,041
  • 36
  • 120
  • 208

3 Answers3

2

Your javascript code should be like below, and in the code, I have added the logout execution in the then() section of the init action. so logout code only executes once init is back with a response from the server.

function onLoad() {
    console.error('onLoad executed.');
    var auth2;
    gapi.load('auth2', function () {
        auth2 = gapi.auth2.init({
           client_id: 'MYAPPIDPLACEHOLDERWHICHIFILLEDOUT.apps.googleusercontent.com'
        }).then(() => {
           auth2 = gapi.auth2.getAuthInstance();
           //check if url contains ?signout=true
           var url = window.location.href;
           if (url.toString().indexOf('?signout=true') != -1) {
              console.error('param found');

              auth2.signOut().then(function () {
                   console.error('User signed out');
              });
            }
         }).catch(err => {
             console.log(err);
         });
        
    });
}
Vishal P Gothi
  • 987
  • 5
  • 15
  • Perfect! Thank you so much! One small follow-up question: do you know why after I'm logged in, never sign out and return to the same page one day later, I'm still signed in? Does Google not auto-expire a session after X hours? And if not, is there a way to do this myself? – Adam Jul 26 '21 at 12:10
  • @Flo Thanks for your upvote, actually you are using onload=onLoad in the script tag so it will always init the session first and it will log out the user when there is matched URL found. so maybe you need to call the onLoad function when the user clicks on Login action maybe should be a button in your application so init will be executed once and not every time when page load. – Vishal P Gothi Jul 26 '21 at 12:23
  • Sure thing, I think we're almost there :) Please check my update 3, because when not using onload to check and not wanting to execute onload each time, the availability of Google's API becomes an issue again. Can you help? – Adam Jul 26 '21 at 12:44
  • *friendly bump* – Adam Jul 29 '21 at 09:49
  • 1
    @Flo Yes, please? I am checking for the issue you mentioned in your last comment so will update to you here. – Vishal P Gothi Jul 29 '21 at 10:13
1

Your problem is most likely that your code is calling the signOut function before the auth2 variable is defined. Based on your code, the callback from gapi.load will not execute immediately, and, because JavaScript is compiled, the

var url = window.location.href;
if (url.toString().indexOf('?signout=true') != -1) {
    console.error('param found');

    auth2.signOut().then(function () {
    console.error('User signed out');
    });
}

part of your code is being called while auth2 is still undefined. Try putting it inside your callback, like so:

function onLoad() {
    console.error('onLoad executed.');
    var auth2;
    gapi.load('auth2', function () {
        auth2 = gapi.auth2.init({
           client_id: 'MYAPPIDPLACEHOLDERWHICHIFILLEDOUT.apps.googleusercontent.com'
        });
        auth2 = gapi.auth2.getAuthInstance();
           
        //check if url contains ?signout=true
        var url = window.location.href;
        if (url.toString().indexOf('?signout=true') != -1) {
            console.error('param found');

            auth2.signOut().then(function () {
                console.error('User signed out');
            });
        }
    });
}
ErrorGamer2000
  • 295
  • 3
  • 8
  • Unfortunately with this I still get that same `Uncaught Error: ga` error as you see in the screenshot above – Adam Jul 21 '21 at 07:30
  • 1
    is it when using the `signOutGoogle` function? It tries to use the `auth2` variable, which is defined in the `onLoad` function, so it cannot use it. – ErrorGamer2000 Jul 21 '21 at 19:15
  • Actually no, that entire function I never call, I removed it from my post for clarity. I added update 2, where I now get `ia` is undefined. It's related to `at qx.a. [as signOut] (cb=gapi.loaded_0?le=ili,ipu:339)`, so it looks like a function in the Google library, but I have no idea where (other than in `onLoad`) this signout function is called... – Adam Jul 22 '21 at 19:35
0
  function onLoad() {
    console.error("onLoad executed.");
    var auth2;

    const oauthLogin = new Promise((resolve, reject) => {
      gapi.load("auth2", function () {
        auth2 = gapi.auth2.init({
          client_id: "MYAPPIDPLACEHOLDERWHICHIFILLEDOUT.apps.googleusercontent.com",
        });
        auth2 = gapi.auth2.getAuthInstance();
      });
    });

    oauthLogin.then(() => {
      if (window.location.href.indexOf("?signout=true") != -1) {
        console.error("param found");
        auth2.signOut().then(function () {
          console.error("User signed out");
        });
      }
    });
  }

You can assign a promise to a variable and execute some code after it's resolved like this. There are multiple ways for achieving that, check Promise.prototype.then() reference.

by the way you don't need to parse window.location.href to String because it location.href is a stringifier that returns a USVString which fits for your purpose.

JoelBonetR
  • 1,551
  • 1
  • 15
  • 21