Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google authentication in firebase showing blank screen Progressive Web App

I am on the way to create my first Progressive web app which uses firebase for storing data. I am also using Gmail as an entry point for all the users that would use the app. However I am stuck on implementing login. Below is my the code for logging in:

html:

<button md-raised-button color="warn" (click)="logInGoogle()"><md-icon>group</md-icon>Sign in with google to enjoy the app</button> 

ts:

logInGoogle(){
    this.authService.loginWithGoogle().then( user => {
      console.log("User is logged in");
      //this.router.navigate(['/addweather']);
    })
    .catch( err => {
      console.log('some error occured');
    })
  }

Here's the service:

loginWithGoogle() {
    return this.afAuth.auth.signInWithPopup(new firebase.auth.GoogleAuthProvider());
  }

Also to check the auth state I have this in my app.component.ts constructor:

this.authService.afAuth.authState.subscribe(
      (auth) => {
        if(auth === null){
          console.log("Not Logged in.");
          this.router.navigate(['login']);
          this.isLoggedIn = false;
        }
        else {
          console.log("Successfully Logged in.");
          this.isLoggedIn = true;
          this.router.navigate(['']);
        }
      }
    )

Now there are a couple of behaviors that the app is showing :

  1. This login functionality works fine on browsers coz if i click on the login button it opens up a new window, authorizes me and comes back to the same tab on which the app is opened.

  2. When I add the app to the home screen and try to login again it prompt me for below options:

enter image description here

Once I click on chrome, it authorizes me and redirects me to the app but the app shows a blank screen now and the oAuth screen just goes on an infinite processing state. Why is this happening? I mean shouldn't it just work the normal way as it worked when the app was run in browser.

Also on clicking the login button it shouldn't prompt the option as shown in the above image; instead it should open an oAuth dialog. I tried doing this also with the following code:

logInGoogle(){
    var newWindow = window.open('https://accounts.google.com/o/oauth2/auth?scope=https://www.google.com/m8/feeds&client_id=9722-j3fstr5sh6pumie.apps.googleusercontent.com&redirect_uri=https://weatherapp321.firebaseapp.com/__/auth/handler&response_type=token', 'name', 'height=600,width=450');

  }

This now instead of prompting with the options opens up a dialog which is desired. But after authorizing, this lands me back to the login page. Why is this happening? when I am already checking the auth state in app.component.ts and redirecting the user to home page if the user gets authorized.

Thanks for being patient and reading till the end. Help would be much appreciated.

Edit

As suggested by Yevgen: Tried with signInWithRedirect. It worked when I first logged in with a slight delay of 2 seconds. But then I logged out and tried to log in again, I get a blank screen after getting logged in.

like image 717
Aakash Thakur Avatar asked Oct 04 '17 16:10

Aakash Thakur


People also ask

What is Google authentication in firebase?

The Firebase Authentication SDK provides methods to create and manage users that use their email addresses and passwords to sign in. Firebase Authentication also handles sending password reset emails. iOS Android Web C++ Unity. Federated identity provider integration.


2 Answers

I had almost same behavior on my pet web app. For my self I solve it by the next steps:

  1. I move firebase initialization to the app.module.ts

@NgModule({
    ...
    providers: [
        { provide: APP_INITIALIZER, useFactory: appConfig, deps: [AuthService], multi: true }
    ]
})

export function appConfig(authService) {
    const app = firebase.initializeApp({
        apiKey
        authDomain
    });
    return () => new Promise((resolve, reject) => {
        firebase.auth()
        .onAuthStateChanged(data => {
            if (data) {
              firebase.auth().currentUser.getToken()
                .then((token: string) => authService.setToken(token););
            }
            resolve(true);
        }, error => resolve(true));
    });
}
  1. Redirection to LoginPage I managed in auth.guard.ts

export class AuthGuard implements CanActivate {
    constructor(
        private authService: AuthService,
        private router: Router
    ) {}

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
        if (this.authService.isAuthenticated()) {
            return true;
        } else {
            this.router.navigate(['/signin']);
            return false;
        }
    }
}
  1. I had the next code in my auth.service.ts

export class AuthService {
    token: string;

    signinUser(email: string, password: string) {
        return new Promise((resolve, reject) => {
            firebase.auth().signInWithEmailAndPassword(email, password)
                .then(resp => {
                    firebase.auth().currentUser.getToken()
                        .then((token: string) => {
                            this.token = token;
                            resolve(resp);
                        }).catch(reject);
                    return resp;
                })
                .catch(reject);
            });
    }

    signoutUser() {
        return firebase.auth().signOut()
            .then(resp => this.token = null);
    }

    getToken() {
        firebase.auth().currentUser.getToken()
            .then((token: string) => this.setToken(token));
        return this.token;
    }
    
    setToken(token) {
      this.token = token;
    }

    isAuthenticated() {
        return this.token != null;
    }
}

I hope it will be helpful for you.

like image 108
Vitali Solyanik Avatar answered Oct 06 '22 11:10

Vitali Solyanik


Looks like on mobile your app opens authentication not a new tab of your current browser but in a new browser, so it cannot make a valid redirect back to your initial browser after authentication with Google. If you will sign in with redirect you will stay in the same browser, so you need to change your service to:

loginWithGoogle() {
    return this.afAuth.auth.signInWithRedirect(new firebase.auth.GoogleAuthProvider());
}
like image 28
Yevgen Avatar answered Oct 06 '22 11:10

Yevgen