1

Update: Due to code refactor, the need for testing that has gone away, and as Ron pointed out in the accepted answer, onAuthStateChange() will fire eventually, and the app can rely on that. I wasn't originally seeing that, which is what motivated my question.

Original Question: I've been using window.localStorage and searching for a key that starts with 'firebase:authUser' as a way to determine if my app can expect a firebase authentication event any time soon. Whether it succeeds or fails, firebase.auth().onAuthStateChanged() is triggered, and I can deal with the result there. The reason for wanting to know is that if I have some local credentials which are being processed, my app can display a 'Please wait...' type message. But if there are none, it can redirect immediately to the login page. Since firebase moved to indexedDB, this code no longer works, and I couldn't find any equivalent hack to look for locally persisted credentials (maybe it's not possible now?).

I'd also be happy to switch to SESSION persistence rather than LOCAL, but I'm not sure if this changes the scenario at all—I'd still need a way to test if there was anything happening to avoid the user being stuck at the 'Please wait...' message forever if there were no local credentials to validate.

Or am I doing this wrong? I know I could show the login page until firebase.auth().onAuthStateChanged() fires, but by then the user might have clicked, and the experience isn't that great either if they already signed in and then refresh the page, where they see the login page again until everything is loaded.

I couldn't find anything in the auth() API to tell if it was in the process of dealing with locally persisted credentials, and up until now, the window.localStorage hack has been working very well. What's the best way to manage the user experience now?

dsl101
  • 1,715
  • 16
  • 36
  • Also posted on Github: https://github.com/firebase/firebase-js-sdk/issues/595. Please indicate when you cross-post, so that others can check both links. – Frank van Puffelen Mar 26 '18 at 14:27
  • Why close it though? I'm happy to cross post, but some people may prefer one channel to the other, and I will always update if a solution is reached in either place. See my comment below though. Is this still not a valid FR? – dsl101 Mar 26 '18 at 18:20
  • I didn't say that it should be closed, merely indicated that it's considered proper etiquette to indicate when you cross-post as to reduce the chance that double work is done. But given that one of our engineers answered here, it makes sense they closed the Github issue to make sure the discussion stays in one place. – Frank van Puffelen Mar 26 '18 at 19:22

2 Answers2

1

You could grey out inputs and disable submit button until .onAuthStateChanged resolves which happens very quickly, usually in under 1 second. Maybe put a linear progress indicator on the login form?

Ronnie Royston
  • 16,778
  • 6
  • 77
  • 91
  • The problem is if there are no saved credentials, you don't get an event, and so the controls would stay disabled. Unless you used the timeout suggested elsewhere, which doesn't seem like a good design. – dsl101 Mar 27 '18 at 11:31
  • Assuming you are using firebase auth, `.onAuthStateChanged` is the heart of your app's state. If it doesn't resolve, you're not online. Offline support would be a specific question unto itself I would imagine... – Ronnie Royston Mar 27 '18 at 17:29
  • This isn't about offline access. The point is that if there are saved credentials, `onAuthStateChanged()` will (eventually) fire. If there are no credentials, it will not. It's currently not possible (as far as i can tell) for the app to tell these 2 situations apart. In your solution, what would re-enable the disabled button in the case where there are no saved credentials? – dsl101 Mar 27 '18 at 22:32
  • 1
    it will always fire if `.auth` is implemented.. It returns `null` if there are no credentials. Try it. `firebase.auth().onAuthStateChanged(function(user) { console.log(user);` – Ronnie Royston Mar 27 '18 at 22:59
  • Well. I've been using that for about ever, and I wasn't seeing that null event. I was only seeing `onAuthStateChanged` fire when a login or explicit logout was processed, not on app initialisation. But a vanilla project did show that up, so thanks for the pointer. I refactored all my firebase.auth code (it was in a couple of modules in a Vue / Vuex / Vue Router app) and now it behaves as you said—must have been an initialisation error in the old code. I'm not sure now whether to mark this as the correct answer though, as the question is moot. What do you think? – dsl101 Mar 28 '18 at 08:41
  • Glad to help. Definitely accept and vote up. ...fir sure :-) – Ronnie Royston Mar 28 '18 at 16:25
1

Relying on underlying implementation is never a good idea instead of provided public API. Firebase has the right to change that at any time. They could have even persisted the user with a different format and that would break your implementation.

That said, you can easily bypass this, by setting your own flag in localStorage when a user logs in and remove it when they sign out. This is better than relying on the hack you had. In this case, you have full control over that flag. You set it anytime a user is signed in after onAuthStateChanged is triggered and remove it on sign out. When a page is loaded you read that value directly to know whether to display the progress bar or not.

bojeil
  • 29,642
  • 4
  • 69
  • 76
  • I agree it's not ideal, hence my FR that Frank has closed :(. My original solution came from here: https://stackoverflow.com/questions/39035594/firebase-retrieve-the-user-data-stored-in-local-storage-as-firebaseauthuser And it's quite possible my app's view of what the firebase might or might not be doing could easily become out of sync, so not really problem solved. But at least _slightly_ better than now. I still think it would be nice if the API would provide status on this, but Frank seems to disagree... – dsl101 Mar 26 '18 at 18:20
  • I never commented on the validity of this as a feature request nor did **I** close the issue you opened on Github. But if you think this would be a good feature to add, [filing a feature request with the Firebase support team](https://firebase.google.com/support/contact/bugs-features/) is the best channel for that. – Frank van Puffelen Mar 26 '18 at 19:23
  • Sorry Frank—the email notification made it look like you'd commented then closed it, and I didn't go to github to check. I was rushing, which is also why no cross-reference. Many apologies.I will file a more complete feature request via that link—although the github issue template does suggest to post feature requests there... – dsl101 Mar 27 '18 at 10:48
  • @bojeil I've submitted a more complete write-up of the FR to the link Frank suggested, and copied the text into the github issue. The github template suggested that was the place for FRs, so I'm not sure which is better... – dsl101 Mar 27 '18 at 11:29