4

Dude, Where's My Function?

Trying to call GoogleUser.signIn() results in TypeError: user.signIn is not a function

Goal

I want to refresh expired credentials (in a single page app) after the user has put their computer to sleep. I've already implemented credential refresh for an active browser window, using auth2.currentUser.listen as described in my answer to: How to refresh expired google sign-in logins?

Since putting your computer to sleep seems to invalidate this method, I need another solution for that edge case. GoogleUser.signIn() seems to fit the bill.

Problem

Documentation in the Google Sign-in API for GoogleUser.signIn() says:

Signs in the user. Use this method to request additional scopes for incremental authorization or to sign in a user after the user has signed out. When you use GoogleUser.signIn(), the sign-in flow skips the account chooser step.

The important part for me is the final part (this is the major difference with GoogleAuth.signIn())

the sign-in flow skips the account chooser step.

Why don't I want to show the account chooser? It's a really poor UX. They may have just signed into my app. They didn't sign out, their computer just went to sleep (possibly for just a second while they were on the phone with their mom).

Unfortunately, trying to call this function results in TypeError: user.signIn is not a function (I'm storing the object in a variable called user).

Ur Codez Suxor, LOL

Maybe, here's a simplified version:

var Auth = {};
Auth.user = null;

// registered as handler for signin component
function onSignIn(googleUser){

    Auth.user = googleUser;

    var auth2 = gapi.auth2.getAuthInstance();

    auth2.currentUser.listen(function(user){

        Auth.user = user;

        // refresh credentials with new user object

    });
}

// called before any action that requires credentials
function getCredentials(callback){

    var expired = Auth.user.getAuthResponse().expires_at < Date.now();

    if(expired){
        var p = Auth.user.signIn(); // <- throws TypeError

        p.then(function(){
            Auth.user = auth2.currentUser.get();
            // refresh credentials here, too
        }); 

    } else {
        return callback();
    }
}
Community
  • 1
  • 1
Waylon Flinn
  • 19,969
  • 15
  • 70
  • 72

1 Answers1

1

Try using GoogleAuth.signIn() instead of GoogleUser.signIn().
For example:

var auth2 = gapi.auth2.getAuthInstance();
auth2.signIn().then(function() {
  ....
});
agektmr
  • 2,144
  • 15
  • 14
  • Thanks for the answer. While this works in some cases, it shows the 'account chooser'. Not only is this a poor UX, it fails when popups are blocked, preventing me from using this solution in handlers not directly connected to user generated events. Do you happen to know of a solution for this? – Waylon Flinn Jun 07 '16 at 16:30
  • Use `.isSignedIn.get()` to detect if the user is already signed in. If signed in, call `auth2.currentUser.get()` as you do in the code to get the profile. Call `auth2.signIn()` only when the user is not signed in. If you can predict the account the user wants to use, add `login_hint: ***@gmail.com` for example to avoid showing the account picker. Sample code that might help: https://github.com/GoogleChrome/credential-management-sample/blob/master/static/scripts/app.js#L236 – agektmr Jun 08 '16 at 02:18