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

Utilizing logic classes in conjunction with styled components

I am seeking a way to utilize this logic in order to assign the appropriate class to an element: <ul onClick={handleClick} className={click ? 'dropdown-menu clicked' : 'dropdown-menu'}> However, as I am employing styled component ...

Transforming HTML with JavaScript

I am facing a challenge in my JavaScript application where I receive HTML code from an endpoint that contains radio buttons. Unfortunately, I cannot modify the HTML content coming from this endpoint. My goal is to convert these radio buttons into regular b ...

Understanding the mechanics of utilizing node modules and requiring them within an Express 4 router

After initiating a node project using an express 4 generator, I have set up the following routing code in the /routes/index.js file: // ./routes/index.js var express = require('express'); var router = express.Router(); router.get('/' ...

React Error: Unable to iterate over this.state.descriptions

Currently facing an issue while trying to resolve this error https://i.stack.imgur.com/BZ304.png The goal is to generate an automated form using the following function: let descriptionsForm = ( <form> {this.state.descriptions.map((d ...

Getting the value of a session variable in JavaScript from a PHP file

Despite the numerous inquiries on this topic, I am still struggling to comprehend it. Scenario: An image with a hyperlink When the image is clicked: Verify if session exists If session exists, open the link If session does not exist, display the login ...

Exploring the Best Integration Point for Firebase in VueJS with VUEX

How can I incorporate Firebase into my Vue.JS application? I am unsure about the best location to place the references to Firebase. ...

Retrieve the JSON array embedded within the JSON string

Can someone help me extract the JSON array from a JSON string? I've been struggling to make it work. Here is the code snippet for reference: // I need assistance with this var all_barcodes = '{"VAM12345":{"colour":"red","size":"32"},"VAM456789" ...

Struggling to convert a JSON file into a TableView within a JavaScript application developed with Appcelerator

Trying to display a JSON file in a table using JavaScript and Appcelerator is proving to be quite a challenge. The output appears as an empty table when compiled to an example page. As someone relatively new to JavaScript and JSON, I'm seeking guidanc ...

How can we deliver pure JS, HTML, and CSS content without relying on static HTML pages?

Looking to create a fast app prototype without using React or Vue? I'd like to avoid simply making an html and js file imported within it. Can npm packages, SCSS be used while programming vanilla Javascript minus a framework? ...

Retrieving a specific time using a JavaScript interface

I am currently implementing a JavaScript control that can be found on this website: My question is, how can I retrieve the selected date from the control in order to pass it to a postback page? I attempted to figure it out myself, but my JavaScript skills ...

Counting the number of PHP inputs in a field

Hello, I am using a PHP script from Steve Dawson's website. To display the output on my HTML page, I am utilizing this AJAX script: <script> $.ajax({ type:'GET', url:'http://www.solariserat.se/count.php', data: ...

Tests using Cypress for end-to-end testing are failing to execute in continuous integration mode on gitlab.com

Challenges with Setting Up Cypress in Gitlab CI We have been facing difficulties setting up Cypress in the CI runners of gitlab.com using the default blueprint from vue-cli to scaffold the project. Despite trying various configurations in the gitlab.yml f ...

Transferring a single dataset from a table to a pop-up modal using Angular

I am working on a table to display entries for a contest, extracted from a database using PHP and converted into a .json object for AngularJS and JavaScript. I want to add a modal feature so that when a "judge" clicks on an entry, they can view its details ...

Mapping a bar chart on a global scale

Are there any methods available to create bar charts on a world map? The world map could be depicted in a 3D view resembling a Globe or in a 2D format. It should also have the capability to zoom in at street level. Does anyone have suggestions or examples ...

Passport JS fails to pass req.user data to Angular Controller

Currently, I am in the process of developing an application that utilizes an Express/Node backend along with Angular JS for the front end. This stack is fairly new to me, and I have been struggling with retrieving data in an Angular Service + Controller. ...

What is the best way to split text copied from a textarea into <p> paragraphs with an equal number of characters in each?

Check out this JSFiddle version I've found a JSFiddle example that seems perfect for my current project needs. However, I'm wondering how to modify the code to ensure that each paragraph is evenly divided with the same number of characters and a ...

Pair a specific portion of text with another string

I'm having trouble finding a substring within a string. The substring and the string are as follows: var str="My name is foo.I have bag(s)" var substr="I have bag(s)" When I use str.match(substr), it returns null, probably because the match() funct ...

How can I efficiently load AJAX JSON data into HTML elements using jQuery with minimal code?

I have successfully implemented a script that loads an AJAX file using $.getJSON and inserts the data into 2 html tags. Now, I want to expand the JSON file and update 30 different tags with various data. Each tag Id corresponds to the key in the JSON strin ...

What purpose does the next() function serve in Express.js?

Using this script to kickstart my next js app. I can't share the entire script, but I do need some assistance with the following: What is the purpose of compression? What is the importance of using helmet? What does next({dev}) do? const express = re ...

Is there a way to retrieve the row and parent width from a Bootstrap and Aurelia application?

Is there a way to determine the exact width of a bootstrap grid row or grid container in pixels using Aurelia? I attempted to find this information on the bootstrap website, but I am still unsure as there are multiple width dimensions such as col-xs, colm ...