pwa google angular firebase firebase-authentication progressive-web-apps

angular - pwa - Autenticación de Google en firebase que muestra la aplicación web progresiva de la pantalla en blanco



angular pwa (3)

Estoy en camino de crear mi primera aplicación web Progressive que usa base de fuego para almacenar datos. También estoy usando Gmail como punto de entrada para todos los usuarios que usarían la aplicación. Sin embargo estoy atascado en la implementación de inicio de sesión. A continuación se encuentra mi código para iniciar sesión:

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''); }) }

Aquí está el servicio:

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

También para verificar el estado de auth , tengo esto en mi constructor app.component.ts :

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(['''']); } } )

Ahora hay un par de comportamientos que muestra la aplicación:

  1. Esta funcionalidad de inicio de sesión funciona bien en los navegadores, porque si hago clic en el botón de inicio de sesión, se abre una nueva ventana, me autoriza y vuelve a la misma pestaña en la que se abre la aplicación.

  2. Cuando agrego la aplicación a la pantalla de inicio e intento iniciar sesión nuevamente, me solicita las siguientes opciones:

Una vez que hago clic en Chrome, me autoriza y me redirige a la aplicación, pero ahora la aplicación muestra una pantalla en blanco y la pantalla de OAuth simplemente pasa a un estado de procesamiento infinito. ¿Por qué está pasando esto? Quiero decir, ¿no debería funcionar de la manera normal, ya que funcionó cuando la aplicación se ejecutó en el navegador?

Además, al hacer clic en el botón de inicio de sesión no debería aparecer la opción como se muestra en la imagen anterior; en su lugar debería abrir un diálogo de oAuth. Intenté hacer esto también con el siguiente código:

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''); }

Esto ahora, en lugar de preguntar con las opciones, abre un diálogo que se desea. Pero después de autorizar, esto me lleva de nuevo a la página de inicio de sesión. ¿Por qué está pasando esto? cuando ya estoy revisando el estado de autenticación en app.component.ts y redirigiendo al usuario a la página de inicio si el usuario obtiene la autorización.

Gracias por ser paciente y leer hasta el final. La ayuda sería muy apreciada.

Editar

Según lo sugerido por Yevgen: intentado con signInWithRedirect . Funcionó cuando inicié sesión por primera vez con un ligero retraso de 2 segundos. Pero luego me desconecté e intenté iniciar sesión nuevamente, aparece una pantalla en blanco después de iniciar sesión.


La autenticación de redireccionamiento no funciona en PWA (en algunos casos es probable que use diferentes instancias de navegador). Puede solucionar esto utilizando el flujo de autenticación emergente :

https://firebase.google.com/docs/auth/web/google-signin

Se vería algo como esto:

firebase.auth().signInWithPopup(provider).then(function(result) { // This gives you a Google Access Token. You can use it to access the Google API. var token = result.credential.accessToken; // The signed-in user info. var user = result.user; // ... }).catch(function(error) { // Handle Errors here. var errorCode = error.code; var errorMessage = error.message; // The email of the user''s account used. var email = error.email; // The firebase.auth.AuthCredential type that was used. var credential = error.credential; // ... });

La única diferencia de flujo es que lanza una ventana de navegador emergente, en lugar de redirigir la instancia actual. Esto simplifica parte de la lógica para obtener el resultado de autenticación también. Si prefiere mantener el flujo normal en personas que no son PWA, puede detectar si la aplicación se lanzó desde la pantalla de inicio:

https://developers.google.com/web/updates/2015/10/display-mode


Parece que en el dispositivo móvil su aplicación abre la autenticación, no una nueva pestaña de su navegador actual sino en un nuevo navegador, por lo que no puede hacer una redirección válida a su navegador inicial después de la autenticación con Google. Si inicia sesión con redirección, permanecerá en el mismo navegador, por lo que necesita cambiar su servicio a:

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


Tuve casi el mismo comportamiento en mi aplicación web para mascotas. Para mi yo lo resuelvo por los siguientes pasos:

  1. Muevo la inicialización de base de fuego a 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. Redirección a LoginPage que administré en 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. Tenía el siguiente código en mi 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; } }

Espero que te sea de utilidad.