在客户端检索由 firebase 分配的用户 ID 令牌时出错

Posted

技术标签:

【中文标题】在客户端检索由 firebase 分配的用户 ID 令牌时出错【英文标题】:error retrieving user Id token assigned by firebase in the client side 【发布时间】:2021-10-19 01:14:47 【问题描述】:

我正在使用基于 JWT 的身份验证,在 express js 中使用 firebase Admin SDK。 根据sign in with custom token,当我们使用函数signInWithCustomToken(token) 为用户签名时,firebase 为该用户设置了一个用户ID 令牌。

根据retrieve id tokens

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

如果用户登录,我们可以获得令牌 但是执行这个我得到错误 getIdToken 值为空。

我把代码改成了

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();

但仍然收到相同的错误 我查找了一些解决方案,发现与我实施的问题类似的答案之一是solution

它使用了 onAuthStateChanged 方法,我正在使用

  <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>

在cdn中,但现在正在获取

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 

我把上面的代码改成了这个

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();

仍然出现未定义 onAuthStateChanged 的​​第二个错误 如何检索用户 ID 令牌?

更新

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`)
        
      

执行上述代码后,这是错误

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

【问题讨论】:

【参考方案1】:

首先,我建议在撰写本文时将 Firebase SDK 更新到最新版本 8.9.1

<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>

如果你看一下documentation 中的onAuthStateChanged 部分,它应该是:

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

除非您调用 getIdTokenRefreshed 函数,否则不会触发 onAuthStateChanged。您可以简单地将该函数重构为:

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`)
  

最后,变量名是userToken,但在请求正文中是body: JSON.stringify(idToken: userToke),您不需要在变量名之前需要await。尝试将getUser 函数重构为:

//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")
)

【讨论】:

const getIdTokenRefreshed = async () => try const user = firebase.auth().currentUser if (user) const token = await user.getIdToken(true) console.log(@987654334 @) return token else console.log("No user is logged in") catch (e) console.log(Something went wrong: $e) 我收到 await 仅在异步函数和顶层有效模块主体 @Vaibhav07 你能用抛出这个错误的最新代码更新你的问题吗?我的意思是函数在我的代码中是异步的 @Vaibhav07 我怀疑该错误是否来自您在问题中添加的函数,因为该函数是异步的......您能否分享错误的屏幕截图并检查错误所在的行号是?还是您忘记保存文件?

以上是关于在客户端检索由 firebase 分配的用户 ID 令牌时出错的主要内容,如果未能解决你的问题,请参考以下文章

优化检索由Firebase的Firestore中的另一个Collection分组的数据

获取firebase android中特定值的推送ID

Firebase 实时数据库能否有效地循环浏览数十亿条帖子并由发布它们的用户检索?

基于 Facebook Id 检索 Firebase uid 的最佳实践

Flutter Firebase 检索不同的用户数据

从 Firebase 中的特定 ID 列表中检索数据,关注用户并仅获取他们的帖子