Vaibhav07
Vaibhav07

Reputation: 223

error retrieving user Id token assigned by firebase in the client side

I am using JWT based authentication using firebase Admin SDK in express js. according to the sign in with custom token when we sign the user with the function signInWithCustomToken(token) firebase sets a user-id token for that user.

according to retrieve id tokens

firebase.auth().currentUser.getIdToken(/* forceRefresh */ true).then(function(idToken) {
  // Send token to your backend via HTTPS
  // ...
}).catch(function(error) {
  // Handle error
});

we can get the token if the user is logged in but executing this I get error that getIdToken value is null.

i changed the code to

const getUser = async () => {
        const token = await firebase.auth().currentUser.getIdToken(/* forceRefresh */true).catch(function(error) {
            console.log(error)
        });
        const userToken = await token;
        const getData = async (userToken) => {            
        const response = await fetch('/getUser', {
            method: 'POST',
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({idToken: userToke})
        })
        const data = await response.json()
        console.log(responnse)
            
        }
    }
    getUser();

but still receiving the same error I looked up for some solutions and found similar answers to the question one of which I implemented was solution

it used onAuthStateChanged method and I am using

  <script src="https://www.gstatic.com/firebasejs/7.14.1/firebase-app.js"></script>
  <script src="https://www.gstatic.com/firebasejs/7.14.1/firebase-auth.js"></script>

in cdn but now am getting

Uncaught (in promise) TypeError: firebase.auth.onAuthStateChanged is not a function
    at profile:40
    at new Promise (<anonymous>)
    at getIdTokenRefreshed (profile:37)
    at profile:50 

I changed the above code to this

firebase.initializeApp(firebaseConfig);
    const getIdTokenRefreshed = async () => {
        return new Promise(async (resolve, reject) => {
           const unsubscribe = await firebase
               .auth
               .onAuthStateChanged(async user => {
                unsubscribe()
                const refreshedToken = await user
                    .getIdToken(true)
                    .catch(err => console.error(err))
                resolve(refreshedToken)
                console.log(refreshedToken)
           }, reject)
        });
    }
    getIdTokenRefreshed();

still getting the second error where onAuthStateChanged is not defined how do I retrieve the user id token?

UPDATE

const getIdTokenRefreshed = async () => {
        try {
          const user = firebase.auth().currentUser
          if (user) {
            const token = await user.getIdToken(true)
            console.log(`Token: ${token}`)
            return token
          } else {
            console.log("No user is logged in")
          }
        } catch (e) {
          console.log(`Something went wrong: ${e}`)
        }
      }

after implementing the above code this is the error

await is only valid in async functions and the top level bodies of modules

Upvotes: 1

Views: 1078

Answers (1)

Dharmaraj
Dharmaraj

Reputation: 50840

First, I'd recommend updating Firebase SDK to latest version which is 8.9.1 at the time of writing this.

<script src="https://www.gstatic.com/firebasejs/8.9.1/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.9.1/firebase-auth.js"></script>

If you take a look at onAuthStateChanged part in the documentation, it should be:

firebase.auth().onAuthStateChanged(...)
//           ^^
// not firebase.auth.onAuthStateChanged

The onAuthStateChanged won't be triggered unless you call the getIdTokenRefreshed function. You can simply refactor that function to:

const getIdTokenRefreshed = async () => {
  try {
    const user = firebase.auth().currentUser
    if (user) {
      const token = await user.getIdToken(true)
      console.log(`Token: ${token}`)
      return token
    } else {
      console.log("No user is logged in")
    }
  } catch (e) {
    console.log(`Something went wrong: ${e}`)
  }
}

Lastly, the variable name is userToken but in request body it is body: JSON.stringify({idToken: userToke}) and you don't need an await before a variable name. Try refactoring the getUser function to:

//const token = await firebase.auth().currentUser.getIdToken(/* forceRefresh */true).catch(function(error) {
//  console.log(error)
//});
//const userToken = await token;

const getUser = async () => {
  const token = await firebase.auth().currentUser.getIdToken(true)
  const response = await fetch('/getUser', {
    method: 'POST',
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({idToken: token})
  })
  const data = await response.json()
  console.log(data)   
  return data 
}

getUser().then(data => {
  console.log("Data received")
})

Upvotes: 1

Related Questions