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 :
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.
When I add the app to the home screen and try to login again it prompt me for below options:
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.
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.
I had almost same behavior on my pet web app. For my self I solve it by the next steps:
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));
});
}
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;
}
}
}
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.
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());
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With