Firebase Authentication JS 不填充 `providerData` 数组

Firebase Authentication JS does not populate `providerData`array

在 VueJS / QuasarJS 应用程序中,我使用 firebase-js-sdk [1] 和 firebaseui-web [2] 来处理身份验证。

在任何已配置的提供商(例如密码、google、苹果等)成功验证后,我想检查用户使用的是哪个提供商。但是在成功验证后,应该包含信息的 user.providerData[] 数组立即为空。

但是 如果我重新加载我的应用程序,user.providerData[] 数组会突然正确填充。

我正在用类似这样的方式检查用户数据

import { getAuth } from "firebase/auth";

const auth = getAuth();
const user = auth.currentUser;

if (user) {
  console.log(user.providerData)
} 

之后,user 对象被完全填充(包括身份验证令牌等),但 user.providerData[] 数组为空。只有在页面重新加载 (CTRL-R) 后,数组才会被填充。

我搜索了项目问题页面和文档,但没有找到任何可以解释这一点的内容。

我很感谢你知道下一步该去哪里!

编辑

正如@aside 所建议的,我使用 onAuthStateChanged 检查用户状态的更新。

  onAuthStateChanged(
    fbAuth,
    (user) => {
      if (user) {
        console.log("onAuthStateChanged: user found");
        console.log("onAuthStateChanged: user.providerData", user.providerData);
        console.log("onAuthStateChanged: user", user);
      } else {
        console.log("onAuthStateChanged: no user found");
      }
    },
    function (error) {
      console.log("onAuthStateChanged:", error);
    }
  );

但即使我在身份验证完成后等待几分钟,user.providerData 数组仍然只在页面重新加载后填充。

这是一个完整的演示:https://codesandbox.io/s/github/perelin/firebase-auth-providerdata-test

提前致谢:)

我正在使用

    "firebase": "9.6.1",
    "firebaseui": "6.0.0",

[1] https://github.com/firebase/firebase-js-sdk
[2] https://github.com/firebase/firebaseui-web

每次更新身份验证状态时,您的代码仅 运行 一次,而不是 运行 一次。 如果您想收听身份验证状态的任何更改,请按照此处所述使用回调和 onAuthStateChanged

https://firebase.google.com/docs/auth/web/manage-users#get_the_currently_signed-in_user

import { getAuth, onAuthStateChanged } from "firebase/auth";

const auth = getAuth();
onAuthStateChanged(auth, (user) => {
  if (user) {
    // Check used provider here
    const providerData = user.providerData;
    // ...
  } else {
    // User is signed out
    // ...
  }
});

身份验证后 checking/requesting 用户对象不起作用的原因是 firebase 可能需要一秒钟来更新 providerData 数组。因此 signInWithX 可能会 return 在 属性 更新之前。

您的应用应在登录后调用getAuth().currentUser.reload()刷新本地用户数据。

这可以在 LoggedIn 视图的 beforeRouteEnter() nav guard 中完成:

// LoggedIn.vue
import { getAuth, signOut } from "firebase/auth";

export default {
  async beforeRouteEnter(to, from, next) {
    await getAuth().currentUser?.reload() 
    next()
  },
}

demo 1

或在 onAuthStateChanged callback:

// main.js
onAuthStateChanged(
  fbAuth,
  async (user) => {
    await user?.reload() 
  },
)

demo 2