如何在提供商登录时在Firebase Auth中定义UID

时间:2019-07-01 23:32:17

标签: firebase firebase-authentication google-identity

我需要定义UID,以一致地确定用户是通过服务器上的自定义令牌还是通过第三方提供商创建的。如果最初无法定义UID,则是否存在以下过程:

  1. 在提供者登录之前创建新用户,以便可以链接提供者凭据
  2. 创建用户之后(使用提供者提供的UID),使用所需的UID创建新用户,将凭据迁移,然后删除原始用户。

它们似乎都是解决通常应该直接解决的问题的困难方法。

编辑:

我们创建一个后端唯一整数User ID并将其存储在SQL数据库中。该userID在所有情况下都用于标识用户。如果通过标准注册过程创建了用户,则将创建该用户,然后使用该用户ID将其存储在Firesbase Auth中。如果第三方提供商创建了该帐户,则该帐户将使用提供商创建的UID存储在Firebase Auth中。该UID可能是字符串,这意味着如果我们尝试将其存储在数据库中,则整个代码库都需要将UID类型从int迁移到字符串。相反,如果Firebase Auth中的UID的值与我们创建的UID相同,则将容易得多,这在我们首次创建用户时就可以完成,但在第三方提供程序创建用户时不可以。我们不维护多个用户ID,即,我们的用户ID与提供者ID不会相同,因此要获取用户并验证令牌,我们要使用我们的用户ID,而不是提供者UID。

2 个答案:

答案 0 :(得分:0)

由身份提供者定义帐户的UID,并确保UID在全球范围内是唯一的。 Firebase不提供生成UID的工具,因为大多数身份提供者已经拥有这样的系统。

答案 1 :(得分:0)

我已经编写了此快速测试功能,以迁移到所需的UID。此功能并不完美,可能会使用更多错误处理功能,例如,如果您在导入新用户时遇到问题,则该用户将被删除并丢失,但是在初始测试中,这就是我要寻找的。理想的情况是,如果admin SDK包含这样的内容,但要更健壮。

用Go语言编写:

    func (AuthImpl) MigrateToUserID(uid string, userID int) (err error) {
    ctx := context.Background()
    var client auth.Client
    client, err = getAuthClient(ctx)
    if err != nil {
        return err
    }

    var userRecord *auth.UserRecord
    if userRecord, err = client.GetUser(ctx, uid); err != nil {
        return err
    }
    userToImport := &auth.UserToImport{}
    userToImport.
        UID(strconv.Itoa(userID)).
        PhoneNumber(userRecord.PhoneNumber).
        CustomClaims(userRecord.CustomClaims).
        Email(userRecord.Email).
        EmailVerified(userRecord.EmailVerified)

    if userRecord.ProviderUserInfo != nil {
        var providers []*auth.UserProvider
        for _, providerUserInfo := range userRecord.ProviderUserInfo {
            providers = append(providers, &auth.UserProvider{
                UID:         providerUserInfo.UID,
                ProviderID:  providerUserInfo.ProviderID,
                Email:       providerUserInfo.Email,
                DisplayName: providerUserInfo.DisplayName,
                PhotoURL:    providerUserInfo.PhotoURL,
            })
        }
        userToImport.ProviderData(providers)
    }

    if err = client.DeleteUser(ctx, uid); err != nil {
        return err
    }

    if _, err = client.ImportUsers(ctx, []*auth.UserToImport{userToImport}); err != nil {
        return err
    }
    return nil
}