I'm currently building an app in Polymer which uses Firebase Authentication to login with your Google+ account or Email. When you run the app it will first check if the user already has a session. If not then the user is being routed to the login page which will display a login form and will handle the login by using <firebase-auth>
by Polymerfire. The login page will notify the user
property upwards to the my-app
(app shell). If the user has been successfully authenticated we send them to the homepage my-app
. This will fire the routePageChanged
observer in my-app
.
_routePageChanged(page) {
if(this.user && this.user.email && this.user.refreshToken) {
this.set("noUser", false);
this.page = page
} else {
this.set("noUser", true);
this.page = 'login';
}
}
Okay, so far so good. If we route a user to the login form and let them authenticate, all is working fine. However, if the user already has a session the routePageChanged
observer in my-app
will fire and won't have a user object yet.
Problem 1
The problem in the example above is that it'll always show the login page for a few miliseconds. We can fix this by adding a timeout (?) on the initial route and show a spinner and wait for the firebase authentication. This seems a little bit hacky as I don't know how long it will take for the user to automatically authenticate? What is the best way to wait for the authentication and then do a route?
Problem 2
In the app-login
page I'm handling the login. I've chosen to use a singInWithRedirect
as I want the login to be available on mobile (popups are being blocked sometimes). The problem with singInWithRedirect
is that it'll also re-render/initialise the whole app after authentication. This means that after creating a valid auth session the routePageChanged
observer in my-app
will be fired and there won't be a user object for a few miliseconds, which will make the app route to /login
.
The _userChanged
function in app-login
will then route back to the overview on its turn. This will also show the login page for a few miliseconds.
<firebase-auth id="auth" user="{{user}}" provider="{{provider}}" on-error="handleError" on-user-changed="_userChanged"></firebase-auth>
_userChanged(event) {
if (event.detail.value.uid) {
this.set("waitingForAuthChanged", false);
this.set("user", event.detail.value);
window.history.pushState({}, null, "/overview");
window.dispatchEvent(new CustomEvent('location-changed'));
}
}
What's the best way to properly handle all these states? I used to use the signInWithPopup
function, this won't initialise the app after authentication. I'm trying to achieve the same with the redirect.