Have you ever encountered the frustration of being unable to navigate to the next page even after successfully logging in due to issues

I'm currently utilizing Vue and Firebase to build my application. One of the features I want to implement is the redirect method using vue-router.

Within my vue-router code, I've included meta: { requiresAuth: true } in multiple pages as middleware.

The redirect logic in my vue-router is designed to send users to /login if the JWT token is not stored in local storage upon login.

Given that I'm leveraging Firebase for user authentication, I expect the user account token to be stored in local storage once a user logs in successfully. Assuming my Vuex code is correct, the vue-router should function as intended.

Upon logging in as a user, the URL remains unchanged. However, when navigating to a specific user's dashboard page, the redirect functionality works smoothly.

I am puzzled by the fact that the URL does not change after logging in. Why might this be happening?

import Vue from 'vue'
import VueRouter from 'vue-router'
//import Home from '../views/Home.vue'
import Dashboard from '../views/Dashboard.vue'
import OrdersMobile from '../views/OrdersMobile.vue'

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    name: 'Home',
    component: () => import(/* webpackChunkName: "about" */ '../selfonboarding/Home.vue')
  },
  {
    path: '/login',
    name: 'Login',
    component: () => import(/* webpackChunkName: "about" */ '../components/Login.vue')
  },
  {
    path: '/dashboard/',
    name: 'Dashboard',
    component: Dashboard,
    meta: { requiresAuth: true },
    children: [
      {
        path: 'products/:id',
        name: 'Products',
        component: () => import(/* webpackChunkName: "about" */ '../views/Products.vue')
      },
      {
        path: 'working-hours/:id',
        name: 'WorkingHours',
        component: () => import(/* webpackChunkName: "about" */ '../views/WorkingHours.vue')
      },
      // {
      //   path: 'pictures/:id',
      //   name: 'Pictures',
      //   component: Pictures,
      // },
      {
        path: 'orders/:id',
        name: 'Orders',
        component: () => import(/* webpackChunkName: "about" */ '../views/Orders.vue')
      },
      {
        path: 'orders.s/:id',
        name: 'OrdersMobile',
        component: OrdersMobile,
        children: [
          {
            path: 'processed',
            name: 'Processed',
            component: () => import(/* webpackChunkName: "about" */ '../views/Processed.vue')
          }
        ]
      },
      {
        path: 'information/:id',
        name: 'Information',
        component: () => import(/* webpackChunkName: "about" */ '../views/Information.vue')
      },
      {
        path: 'information.s/:id',
        name: 'InformationMobile',
        component: () => import(/* webpackChunkName: "about" */ '../views/InformationMobile.vue')
      },
    ]
  }
]


const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes,
})


router.beforeEach((to, from, next) => {
  if(to.matched.some(record => record.meta.requiresAuth)) {
      if (localStorage.getItem('jwt') == null) {
          next({
              path: '/login',
              params: { nextUrl: to.fullPath }
          })
      } 
  } else {
      next()
  }
})


export default router

Vuex Code at ../store/user.js

import 'firebase/firebase-auth'
import fireApp from '@/plugins/firebase'
import router from '../../router'
const firebase = require("firebase");
require("firebase/firestore");
const db = firebase.firestore();

const state = {
    currentUser: null
}

const getters = {
    currentUser: state => state.currentUser
}

const mutations = {
    userStatus: (state, user) => {
       
        user === null ? state.currentUser = null : state.currentUser = user.email
      }
}

const actions = {
 signIn: async ({ commit }, user) => {
    try {
      const userData = await fireApp.auth().signInWithEmailAndPassword(
          user.email,
          user.password
      );

        // Get the user id (from the user object I guess)
        const userId = fireApp.auth().currentUser.uid;
        // or maybe through  const userId = fireApp.auth().currentUser.uid;

        const proUserDocRef = db.collection('ProUser').doc(userId);
                    
        proUserDocRef.get().then((doc) => {
                if(doc.exists && doc.data().status === true) {
                    router.push({name:'Products',params:{id: userId}}).catch(err => {})
                } else if(doc.exists && doc.data().status === false){
                    router.push({name:'Welcome',params:{id: userId}}).catch(err => {})
                } else {
                    alert('You are not registered as a pro user.')
                }
        })

        
    }
    catch(error) {
        const errorCode = error.code
        const errorMesage = error.message
        if(errorCode === 'auth/wrong-password') {
            alert('wrong password')
        } else {
            alert(errorMesage)
            }
        }
    },

    signOut: async({ commit }) => {
        try {
            await fireApp.auth().signOut()
        }
        catch(error) {
            alert(`error sign out, ${error}`)
        }
        commit('userStatus', null)
    }
}

export default {
    state,
    mutations,
    getters,
    actions
}

Answer №1

The beforeEach navigation guard is missing a critical step when handling authentication and logged-in users:

router.beforeEach((to, from, next) => {
  if(to.matched.some(record => record.meta.requiresAuth)) {
      if (localStorage.getItem('jwt') == null) {
          next({
              path: '/login',
              params: { nextUrl: to.fullPath }
          })
      } else {
          next();     // Don't forget this important call ✅
      }
  } else {
      next()
  }
})

Answer №2

After some troubleshooting, I managed to successfully implement the following code snippet into the user.js actions section:

const token = await firebase.auth().currentUser.getIdToken(true)
localStorage.setItem('jwt', token)

As a result, I was able to address the issue I was facing.

Initially, I struggled with setting the jwt token in the local storage, but eventually solved it by incorporating this step when logging into the website.

I also realized that I had forgotten to include 'next()' in my code.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips on how to highlight a clicked list item:

I'm currently attempting to access the key={1} Element within my li. My goal is to set the activeItem in State in order to compare it with the clicked item later on. If they are equivalent, I want to apply an active class to that specific element. How ...

Exploring the process of retrieving data from localStorage in Next.js 13

Having recently delved into the realm of Next JS, I've encountered a hurdle when it comes to creating middleware within Next. My aim is to retrieve data from local storage, but I keep hitting roadblocks. middleware.ts import { key, timeEncryptKey, to ...

How to use jQuery to iterate over changing elements and retrieve their data values

Exploring the potential of a collapsible panel to meet my requirements $(".sport").on("click", function() { var thisId = $(this).attr("id"); var thisChildren = $(this) + ".sportlist"; $(thisChildren).each(function(index) { }); }); <link ...

The problem with Vue JS static links

I'm currently working with a Vue.js application (v2). I've noticed that if I skip visiting the root of the site, the sub-links do not work properly. For example: Visit: Then go to If I directly visit: I encounter the following error messag ...

Utilize the power of REACT JS to transform a specific segment within a paragraph into a hyperlink. Take advantage of the click event on that hyperlink to execute an API request prior to

In React JSX, I'm encountering an issue trying to dynamically convert a section of text into an anchor tag. Additionally, upon clicking the anchor tag, I need to make an API call before redirecting it to the requested page. Despite my attempts, I have ...

Achieving 10 touchdowns within a set of 5 plays during a football game

Receiving a page from an external site where I have no control. The table structure is as follows: <table><tbody> <!-- headers --> <tr><td></td> <td></td> <td></td> <td>< ...

Tips for updating HTML Ajax content when the back button is clicked

I created a search page with filters that update the URL parameters to prevent values from being lost if the page is refreshed. q = $('#form input[name=q]').val(), srchtype= $('#filter input[name=srchtype]:checked').val(), sortBy ...

ESLint version 8.0.0 encountered an error while attempting to fetch the '@typescript-eslint' plugin

Hey there, I'm in need of some assistance. I encountered an error while trying to build a project. Uh-oh! Something didn't go as planned! :( ESLint: 8.0.0 TypeError: Failed to load plugin '@typescript-eslint' specified in ' ...

Analyzing and refreshing the data entries in firebase database

https://i.stack.imgur.com/ZMjck.png I have been attempting to modify my Username password group name. However, the update process is not successful. I am looking for a way to compare data before updating fields, but I am unable to find a suitable method. ...

Error: Unable to modify a property that is marked as read-only on object '#<Object>' in Redux Toolkit slice for Firebase Storage in React Native

Hey there! I've been working on setting my downloadUrl after uploading to firebase storage using Redux Toolkit, but I'm facing some challenges. While I have a workaround, I'd prefer to do it the right way. Unfortunately, I can't seem to ...

What is the process for triggering property decorators during runtime?

Wondering about dynamically invoking a property decorator at runtime. If we take a look at the code snippet below: function PropertyDecorator( target: Object, // The prototype of the class propertyKey: string | symbol // The name of th ...

Safari is encountering an issue with the value provided for the width/height attribute in the <svg> element, as it is not a recognized

When adjusting the size of an SVG based on antd breakpoints, I encountered errors like these. I am passing props to an SVG element: const { lg } = useBreakpoint(); const height= lg ? "8rem" : xs ? "3rem" : "5rem"; const width ...

Steps for resetting the Vue 3 scaffolding

Two options to scaffold a new Vue project are npm init vue@latest and npm create vue@3. I recall there is a specific command that allows you to re-initialize the scaffolding process in order to add additional features like TypeScript or Cypress. Unfortuna ...

Husky and lint-staged failing to run on Windows due to 'command not found' error

I'm facing issues with getting husky and lint-staged to function properly on my Windows 10 system. Here's how my setup looks like: .huskyrc.json { "hooks": { "pre-commit": "lint-staged" } } .lintstagedrc ( ...

Issue when Updating Component State: React child cannot be an object

I'm currently in the process of familiarizing myself with React and how to manage component state. My goal is to build a component, set up the initial state using a constructor, make a GET request to the server to fetch an array of objects, and then ...

I'm experiencing an issue where my drum app element does not refresh after performing an action dispatch

Struggling with my React/Redux drum app, I'm at a roadblock with the final component that should update with the selected object's ID through an action dispatch. It baffles me why the element won't reflect the changes even though I've c ...

Is it possible to integrate a backbone model with Angular?

Below is an example of a Backbone post model: var Post = Backbone.AssociatedModel.extend({ urlRoot: ApiService.resolveRESTUrl('posts'), defaults: { age : 0, fname : "", lname : "", manager : null }, ...

Retrieve Backbone data immediately following a successful Save operation

Is there a way to trigger a fetch right after saving data? I'm looking to immediately retrieve information after a successful post... Below is the code snippet in question: search: function (search) { searchM = new SearchM(); searchM.sa ...

Optimal method for managing user session data in Vue with the power of Laravel and Inertia

I am creating an application that features a dynamic menu using Laravel, Vue, and Inertia. To transmit the session details about the menu items to be displayed (such as icons) and user information (like avatar and name), I currently rely on the HandleIner ...

Allow users to zoom in and out on a specific section of the website similar to how it works on Google Maps

I am looking to implement a feature on my website similar to Google Maps. I want the top bar and side bars to remain fixed regardless of scrolling, whether using the normal scroll wheel or CTRL + scroll wheel. However, I would like the central part of the ...