Home > Software engineering >  After onauthstatechanged still currentuser is null
After onauthstatechanged still currentuser is null

Time:08-10

I am trying to make Axios request with Bearer token.
This is my Axios function.

import axios from "axios"
import {auth} from '../../config/firebase.config'

    export function createRequest(upload) {
        const tenantId = localStorage.getItem("tenantId")
        const isUser = auth.onAuthStateChanged((user) => {
            if (user) {
                return auth.currentUser
            }
        });
    
        if (isUser) {
            const user = auth.currentUser;
            const idToken = user.getIdToken(true);
            return axios.create({
                baseURL: `${process.env.REACT_APP_BASE_API_URL}/${tenantId}/`,
                headers: {
                    "Content-type": !upload ? "application/json" : "multipart/form-data",
                    Authorization: `Bearer ${idToken}`
                }
            })
        }
        return null
    }

But the problem is my user id always returns null. I refer this link on StackOverflow and firebase doc. I did everyting according to the docs. But still not working.

CodePudding user response:

The onAuthStateChanged observer waits until the related observable emits an event. However, Javascript does not wait hence auth object might be in intermediate state. Document reference: https://firebase.google.com/docs/auth/web/manage-users#get_the_currently_signed-in_user.

Move your code inside subscription:

import axios from "axios"
import {auth} from '../../config/firebase.config'

    export function createRequest(upload) {
        const tenantId = localStorage.getItem("tenantId")
        return auth.onAuthStateChanged((user) => {
            if(user){
                const idToken = user.getIdToken(true);
                return axios.create({
                    baseURL: `${process.env.REACT_APP_BASE_API_URL}/${tenantId}/`,
                    headers: {
                        "Content-type": !upload ? "application/json" : "multipart/form-data",
                        Authorization: `Bearer ${idToken}`
                    }
                })
            }else{
                return null;
            }
        });
    }

I am not 100% sure about the code above since I cannot test it. You can try different variations and ask more.

Related questions:

CodePudding user response:

The callback that you pass to onAuthStateChanged isn't expected to return any value, so your return auth.currentUser never ends up anywhere:

const isUser = auth.onAuthStateChanged((user) => {
    if (user) {
        return auth.currentUser
    }
});

One solution is to create your own Promise on top of onAuthStateChanged as bojeil showed in this GitHub issue:

function getCurrentUser(auth) {
  return new Promise((resolve, reject) => {
     const unsubscribe = auth.onAuthStateChanged(user => {
        unsubscribe();
        resolve(user);
     }, reject);
  });
}

With that, your code could become:

const isUser = await getCurrentUser(auth);

Of (if you can't use await):

getCurrentUser(auth).then((user) => {
  ...
})
  • Related