0

In my routes array in main.js, I have set

meta : { requiresAuth: true }

for every component except on the UserLogin page.

Regarding navigation resolution, I have set a check before each route as follows:

router.beforeEach((to, from, next) => {
    const currentUser = firebase.auth().currentUser;
    const requiresAuth = to.matched.some(record => record.meta.requiresAuth);
    const currentUserState = !!currentUser;

    console.table({ currentUserState, requiresAuth });

    if (requiresAuth && !currentUser) {
        next('/login');
    } else {
        next();
    }
}

With this setup, everything almost works as expected/intended. Logged in users can go anywhere, and anonymous users are redirected to localhost/login.

However, this checking and redirecting only functions when users are navigating by clicking the links in the web app (which are all <router-link>s that go :to="{ name: 'SomeComponent' }".

When any user (registered or anonymous) attempts to navigate their way around the app by typing or copy pasting urls, the app will automatically send them to the login page.

From the console.table output, I can see that manually entering urls always results in currentUserState being false.

It does not remain false: a user that has logged in (currentUserState === true), who then manually navigates somewhere (currentUserState === false), has their currentUserState revert back to true

I can only vaguely guess that the problem is related to rendering and firebase.auth().

4
  • need to see how you are initializing firebase... i would guess that you are setting up the routes before firebase is initialized so when a user enters a url the router is being called before firebase is initialized therefore there is no user Commented Oct 12, 2018 at 3:27
  • @AaronSaunders I have a database.js file where my config object lives. app = firebase.initializeApp(confg) happens in this file, and db = app.database(); is exported. database.js is not called in main.js Commented Oct 12, 2018 at 3:49
  • firebase.initializeApp(confg) does not resolve the current user... Commented Oct 12, 2018 at 3:58
  • @AaronSaunders Thanks for your reply. I require clarification on what you mean by 'resolve' the current user, or rather, how to make available the ability to call firebase.auth().currentUser in the router.beforeEach callback in main.js Commented Oct 12, 2018 at 4:18

2 Answers 2

1
firebase.initializeApp(config)

// you need to let firebase try and get the auth state before instantiating the 
// the Vue component, otherwise the router will be created and you haven't 
// resolved whether or not you have a user

firebase.auth().onAuthStateChanged(function(user) {
    app = new Vue({
      el: '#app',
      template: '<App/>',
      components: { App },
      router
    })
});
Sign up to request clarification or add additional context in comments.

Comments

0

I have found a solution to this bug.

In my Vuex store.js, a snapshot of the state is stored into localStorage. This snapshot is updated any time there is a change to the store itself, so the localStorage backup is always up-to-date with the actual state of the Vue.js application itself.

store.subscribe((mutation, state) => {
  localStorage.setItem('store', JSON.stringify(state));
});

This store.subscribe is set in my store.js just before the export line.

A function called initStore is also defined in the store as follows

initStore(state) {
  if (localStorage.getItem('store')) {
    this.replaceState(Object.assign(state, JSON.parse(localStorage.getItem('store'))));
  }
},

and after my store object, it is immediately called with store.commit('initStore').

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.