$http post works on browser but not on device


#1

I’m doing google login and I’m having problem with $http post method for retrieving access token. I’ve made a factory that handles login and gathering data after successful login. The problem is that POST method takes some time and the view is already trying to load. So I decided to deal with that problem using $q.defer() and it all works fine in the browser but when I try it on my phone it won’t work.

This is what happens in my controller:

$scope.googleLogin = function() {

        OpenGoogle.login().then(
            function () {
                $location.path('/menu');
            },
            function () {
                alert('OpenGoogle login failed');
            }
        );
};

In OpenGoogle factory this is my login function:

function login() {

        deferredLogin = $q.defer();


        tokenStore['loginType'] = 'google';

        var loginWindow = $window.open(GOOGLE_CODE_URL + '?scope=email%20profile&redirect_uri=' + redirectURI + '&response_type=code&client_id=' + googleClientID, '_blank', 'location=no');

        if(runningInCordova) {
            loginWindow.addEventListener('loadstart', function(event) {
                var url = event.url;
                if (url.indexOf("code=") > 0 || url.indexOf("error=") > 0) {
                    loginWindow.close();
                    oauthCallback(url);
                }
            });

            loginWindow.addEventListener('exit', function () {
                // Handle the situation where the user closes the login window manually before completing the login process
                deferredLogin.reject({error: 'user_cancelled', error_description: 'User cancelled login process', error_reason: "user_cancelled"});
            });
        }
        return deferredLogin.promise;
    }

And my oauthCallback looks like this:

function oauthCallback(url) {
        var code,
            obj, request;
        if (url.indexOf("code=") > 0) {
            code = url.substr(url.indexOf('=') + 1);
            $http({
                method: "POST",
                url: GOOGLE_TOKEN_URL,
                data: {
                    code: code,
                    client_id: googleClientID,
                    client_secret: googleClientSecret,
                    redirect_uri: redirectURI,
                    grant_type: 'authorization_code'
                }
            })
            .success( function(data) {
                tokenStore['googleToken'] = data.access_token;
                tokenStore['googleRefreshToken'] = data.refresh_token;
                var now = new Date().getTime();
                //Calculate exactly when the token will expire, then subtract
                //one minute to give ourselves a small buffer.
                tokenStore['googleExp'] = now + parseInt(data.expires_in, 10) * 1000 - 60000;
                deferredLogin.resolve();
            })
            .error( function(data, status, headers, config) {
                alert('failed!');
            });
        } else if (url.indexOf("error=") > 0) {
            deferredLogin.reject(obj);
        } else {
            deferredLogin.reject({error: 'error occurred', error_description: 'Unknown', error_reason: "Unknown"});
        }
    }

For some reason on my phone I get an alert OpenGoogle login failed as if promise returns reject but in my browser everything works fine.


#2

It could also be that the app does not have appropriate internet permissions. You should check if its in phone’s browser, or if other internet functions are working.


#3

No, unfortunately it is not internet problem, other internet funciona are working normally.


#4

Have you whitelisted the URL?

https://docs.angularjs.org/api/ng/service/$sce


#5

Yes, I’ve tried with that too, and still I got the same alert.
When I put the deferredLogin.resolve(); outside of http callback then function just run through the code and returns, before http post retrieves the data. That’s why I’ve put deferredLogin.resolve(); inside the success callback. I hope that I’m doing that part right.