有没有办法在 Firebase 中创建经过身份验证的用户 ID 之前更改它们。它们是由 facebook 提供商创建的

Is there a way to change an authenticated user id right before they are created in Firebase. They are created by the facebook provider

我们正在使用 firestore 将 MongoDB 数据库迁移到 Firebase。现在我们有一个 Firebase 应用程序,我们在其中使用 firestore 来保存每个用户的数据。我们想使用 Firebase 身份验证来登录我们的用户。我们的 Firestore 中已经有用户,他们在 Firestore 中的用户文档中有一个 Facebook ID,我们想用它来创建 Auth 帐户。

我们无法使用云函数以编程方式创建 Facebook 用户。所以我们想到的解决方案是,当一个用户被创建时(通过 facebook 用户登录),我们创建一个云函数来检查新 Facebook 用户的 id 是否已经存在于我们的 firestore 中。这是行不通的,因为身份验证 uid 是在创建时定义的,我们无法更改它。我们希望此身份验证 ID 与该用户的文档名称相同。


我们想到的解决方案

重定向新用户的新集合

我们的第一个计划是制作一个新的文档集合,我们将使 facebook 用户的 uid 使用他们的旧 uid 重定向到他们的文档。

这种方法的问题在于,我们每次 查找此人时都必须阅读这份新文档。这基本上会使我们的阅读量增加一倍,并使我们的 firestore 账单价格增加一倍。

更改文档名称

另一个计划是更改用户文档的名称。这将使我们能够将新的经过身份验证的用户视为普通用户而无需太多更改。而且可以自动化。

这种方法的问题是我们必须更改对用户的所有引用,这会导致大量读取和额外工作。用户玩过的所有游戏,他们所有的友谊。对于成千上万的用户,这可能会导致很多。这可能会出错很多。


我们正在尝试找出解决此问题的方法。我们会喜欢任何可以将我们推向正确方向的反馈或建议。如果有任何不清楚的地方,我很乐意听到问题。感谢阅读!

控制 Firebase 身份验证的 UID 的唯一方法是 creating a custom provider. With that you can create custom tokens 在 Cloud Functions 或其他受信任的环境中使用您想要的任何 UID。

您应该能够通过结合使用 firebase 身份验证触发器和自定义声明来解决此问题。

授权触发器

首先,创建一个 firebase 身份验证触发器函数,该函数将在创建用户帐户后启动。

import { auth } from 'firebase-functions';

export const onUserCreate = auth.user().onCreate((user) => { ... })

在触发器函数中,您可以读取一次您需要的文档,并使用admin sdk 将其值添加到自定义用户声明中。

添加声明

import * as admin from 'firebase-admin';

...
const claims = user.customClaims || {};
admin.auth().setCustomUserClaims(user.uid, { ...claims, oldFacebookId: "value here"  });
...

消费声明

虽然需要通过 admin sdk 添加自定义声明,但当您的用户登录时,它们可以在客户端毫无问题地使用。

firebase.auth().onAuthStateChanged((user) => {
      if (user) {
        user?.getIdTokenResult().then((token) => {
          const oldFacebookId: token.claims.oldFacebookId;
          ... do what you need with it
         });

       return;
      }
});

通过结合使用 onAuthStateChanged 侦听器和 getIdTokenResult,您将能够在您的用户登录或他的状态被您应用上的 firebase SDK 自动刷新的任何时候访问声明.