Experiencing issues with Firebase authentication on Nuxt app when refreshing the page for beginners

Despite my efforts of trying numerous examples and methods, I am still stuck in this situation - I have been struggling with it for the past 2 days now... The issue I am facing is that my app functions properly when I log in and click on links, but if I refresh the page or directly access a URL in the browser, Firebase seems to no longer recognize the authenticated session.

Edit Upon further thought, I believe this occurs because when the page is refreshed, Vue's server makes the request. Whereas, when clicking on a link, the client initiates the request... The main difference being that no session or cookie is set or sent during the server request. Is the solution redirecting the page? Or is there a way to send the browser's cookie/session as the page loads? Alternatively, should a server-to-server authentication be established between Vue and Firebase, and then manage the logged-in state through Vue/Vuex?

This is the error message received from Firebase:

Error encountered while retrieving list of presentations! FirebaseError: [code=permission-denied]: Missing or insufficient permissions. 

Here is my current approach:

Firstly, within my store/index.js file, we decode the user data stored in a cookie and dispatch it to an action named setUserLoggedIn (Note: the same value is set twice intentionally for completeness.)

This code appears to be functioning correctly (i.e., gets executed whenever Nuxt is initialized. This step ensures that the user data from the cookie is available in our Vuex store before proceeding). It decodes the cookie and sends the expected values to setUserLoggedIn.

    import { getUserFromCookie } from '@/helpers'
export const actions = {
  async nuxtServerInit({ dispatch }, { req }) {
    const user = getUserFromCookie(req)
    console.log('This code executes first with user ' + JSON.stringify(user))
    if (user) {
      console.log('A user cookie was found - possibly can initiate login')
      await dispatch('user/setUserLoggedIn', {
        email: user.email,
        uid: user.user_id,
        thisUserId: user.user_id
      })
    }
  }
}

Then, the Login Status and User details are committed back to Vuex state through two mutations, followed by confirming the user's logged-in status with Firebase:

 setUserLoggedIn({ commit }, user) {

    commit('LOGIN_STATUS', true)
    console.log(`Re-affirming login user object is ${JSON.stringify(user)}`)
    commit('LOGIN_USER', {
      loginInstanceId: 'a-key-to-track-each-login-session',
      userUniqueId: user.thisUserId,
      emailAddress: user.email,
      uid: user.thisUserId
    })
    return UserService.affirmLogin(user)
  },

Lastly, a check was made to determine if there is an active session with Firebase (firebase.auth().currentUser returns undefined). Other attempts using different Firebase commands to monitor state changes also did not yield any results... Everything tried so far has been unsuccessful.

  async affirmLogin(myUser) {
    const currentUser = await firebase.auth().currentUser
    console.table(currentUser)
  },

A token containing the Firebase token is also set:

await firebase
        .auth()
        .signInWithEmailAndPassword(user.emailAddress, user.password)
        .then(() => {
          firebase.auth().onAuthStateChanged(user => {
            currentUser = user.uid
          })
        })
      const token = await firebase.auth().currentUser.getIdToken(true)
      Cookies.set('access_token', token) // saving token in cookie for server rendering

I have tried numerous approaches - from configuring Vuex state/getters and Firebase commands, to extensively commenting out sections of the code, debugging, etc. but I cannot identify why it isn't functioning properly. Specifically, Firebase appears to disregard or cannot detect the existing session upon refresh, despite the presence of a cookie and what seems like data in the Vuex store.

However, it does work if I navigate to a page through the UI that triggers the specified route above (i.e., submitting a form button to activate affirmLogin).

I suspect that something might be off with the session, but I am unable to pinpoint the exact issue. Additionally, I am uncertain how Firebase is meant to capture the user ID upon refresh. While other examples seem to depict it effortlessly working, this hasn't been the case for me :( Any assistance would be greatly valued!

Thank you

Answer №1

Admittedly, my knowledge of Vue, Nuxt, and Firebase is limited, but I have a hunch that the issue lies in Firebase not fully initializing when you request the currentUser. The Firebase documentation seems to support this notion:

Note: currentUser may be null because the auth object hasn't finished initializing. If you're using an observer to track user sign-in status, you shouldn't need to handle this scenario.

Have you considered implementing an authentication state observer? Here's an example snippet:

firebase.auth().onAuthStateChanged(function(user) {
  if (user) {
    // User is signed in.
  } else {
    // No user is signed in.
  }
});

I suggest integrating this early in your code to ensure you capture any changes in authentication status. You could start with something like this:

setUserLoggedin({ commit }, user) {
  const userPromise = new Promise((resolve, reject) => {
    firebase.auth().onAuthStateChanged(function(user) {
      if (user) {
        // User is signed in.
        console.log('got user', user);
        resolve(true);
      } else {
        // No user is signed in.
        resolve(false);
      }
    });
  });

  commit('LOGIN_STATUS', true);

  console.log(`Re-affirming login user object is ${JSON.stringify(user)}`);
  commit('LOGIN_USER', {
    loginInstanceId: 'a-key-to-track-each-login-session',
    useruniqueid: user.thisUserid,
    emailaddress: user.email,
    uid: user.thisUserid,
  });

  return userPromise;
}

This might not serve as a definitive solution, but it could potentially steer you in the right direction if my assumption proves correct.

Answer №2

I encountered a similar issue where I kept getting an unauthenticated error after refreshing or reloading the page. The problem stemmed from the propertyName of the user endpoint. If you are returning the user directly without using an object like 'user':{...}, you need to include propertyName : false in the auth options of the nuxt config. You can verify what authentication result will be received by running this code snippet:

let user = await this.$auth.requestWith(    
    'local',    //strategy name
    null,       //endpoint
    { url: '/api/user', method: 'get', propertyName: false } // options.endpoints.user
);

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

The functionality of CKEDITOR.tools.getindex has not been found

I'm currently in the process of updating my CKEDITOR version from 4.4.1 to 4.5.1. In order to do this, I am uploading my build-config.js file to ensure that I have all the same plugins as before with the latest CKEDITOR version. The issue arises when ...

You are attempting to access 'https://open-api.trovo.live/openplatform/channels/id' from the source 'http://localhost:3000'

I've encountered an issue while trying to retrieve profile data from the Trovo API. Access to fetch at 'https://open-api.trovo.live/openplatform/channels/id' from origin 'http://localhost:3000' has been blocked due to CORS policy ...

transform constant values into API requests using React

The sample dataset mentioned will be retrieved from a backend API call handled by Flask. The API has already been configured on the backend. const rows = [ { name: "XYZ", age: "12", email: "<a href="/cdn-cgi/l/emai ...

Display a dropdown menu when clicking on a close button in a single element using Vanilla JavaScript

I'm currently in the process of learning Javascript and trying to grasp the concept of events and selectors. My aim is to have a close button that, when clicked, triggers a specific dropdown related to the card it's attached to. I plan to achie ...

Using Typescript/JSX to assign a class instance by reference

Looking to access an object's property by reference? See the code snippet below; class Point{ x:number; y:number; constructor(x,y) { this.x=x; this.y=y; } } const a = { first: new Point(8,9), second: new Point(10,12) }; let someBoo ...

An unusual 'GET' request has been made to the '/json/version' endpoint in Express.js

Hey there, I'm facing a challenge with my Express project. For some reason, I keep receiving a 404 error due to a mysterious GET request to '/json/version'. The request seems to bypass the defined routers after adding session data and eventu ...

What is causing the dysfunction of angular2 form when used with the HTML <form> tag?

Can someone explain the strange behavior of the <form> element in ng2 to me? I have noticed something odd and need some clarification :) To demonstrate, I have created a simple Plunker example at this link: https://plnkr.co/edit/vdrHJBNdd26y6YhPXTHD ...

Avoiding redundant code in React Components: Best practices to keep your code DRY

I am currently utilizing React with Material UI v1.0 to implement a list, but I want to avoid code repetition. Here is the existing code: import List from 'material-ui/List'; import DashboardIcon from 'material-ui-icons/Dashboard'; ...

Enhanced Stay Connected feature for inclusions and exclusions

I am facing an issue with excluding multiple components from my KeepAlive component. Despite trying to exclude more than one component, it seems to only work for a single component. <KeepAlive exclude="DetailView, NewClaim"> <router- ...

Adjust the styling of selected elements when their values are changed

I am attempting to modify the background color based on the selected value that is returned. However, my current code doesn't seem to be working as expected: <script> $(document).ready(function() { $('#assessments').change(functi ...

Conceal the iframe if the source is http:// and there is no associated

Is there a way to hide the iframe only if the src starts with "http://"? This is what I have tried so far: <script type="text/javascript> if ( $('iframe[src^="http://"]') ) document.getElementById('iframe').style.d ...

Issue with installing vscode-ripgrep during VSCode build/run process

After attempting to build and run VSCode on my Ubuntu 17.10 by following the instructions from this guide: https://github.com/Microsoft/vscode/wiki/How-to-Contribute#build-and-run, I encountered an issue when installing dependencies using yarn. The error m ...

Is it possible to implement UseState in Server-Side-Rendering scenarios?

Is it possible to utilize useState (and other react hooks?) with Server Side Rendering? I keep encountering the following error when attempting to execute the code: TypeError: Cannot read property 'useState' of null. Oddly enough, if I disable ...

Tips for optimizing mobile performance by loading .obj models into objects on three.js

How can I properly load .obj models with objLoader and MTLLoader for my three.js mini game? I am facing an issue where the game loads fine on computers but fails to load on mobile browsers. Specifically, when accessed on a phone browser, the game attempts ...

An error was encountered: An identifier that was not expected was found within the AJAX call back function

I am experiencing an issue while attempting to query an API. An Uncaught SyntaxError: Unexpected identifier is being thrown on the success part of my JQuery Ajax function. $(document).ready(function(){ $('#submitYear').click(function(){ let year ...

Why is it possible to import the Vue.js source directly, but not the module itself?

The subsequent HTML code <!DOCTYPE html> <html lang="en"> <body> Greeting shown below: <div id="time"> {{greetings}} </div> <script src='bundle.js'></script& ...

How to retrieve the selected values of specific option tags using jQuery?

I have a situation where I need to select an option from a dropdown menu. Here is the code for the dropdown: <select id="customUser_id" name="customUser_id"> <option value="2" label="Friends Of Friends">Friends Of Friends</option> &l ...

Combining round brackets and square brackets when initializing an array

In the snippet below, values are assigned with a mix of parentheses and square brackets without any errors. However, most other combinations (such as parentheses inside square brackets) do not work at all. var myItems = []; myItems[5] = ("A1", "B1", ["C1" ...

Webpack does not support d3-tip in its current configuration

I'm having some trouble getting d3-tip to work with webpack while using TypeScript. Whenever I try to trigger mouseover events, I get an error saying "Uncaught TypeError: Cannot read property 'target' of null". This issue arises because th ...

Exploring nested static properties within TypeScript class structures

Check out this piece of code: class Hey { static a: string static b: string static c: string static setABC(a: string, b: string, c: string) { this.a = a this.b = b this.c = c return this } } class A { static prop1: Hey static ...