从Firebase中删除特定用户

56

有没有一种方法可以从Firebase获取特定的用户账户,然后将其删除?

例如:

// I need a means of getting a specific auth user.
var user = firebase.auth().getUser(uid);
// Note the getUser function is not an actual function.

然后,我想删除该用户及其附加数据:

// This works
user.delete().then(function() {
   // User deleted.
   var ref = firebase.database().ref(
      "users/".concat(user.uid, "/")
   );
   ref.remove();
});

Firebase文档指出,如果用户当前已登录,则可以删除用户:

firebase.auth().currentUser.delete()

我的目标是允许已登录的管理用户从系统中删除其他用户。


你能详细说明一下你的代码为什么“不工作”吗?你期望发生什么,实际上又发生了什么?如果你遇到了异常或错误,请在帖子中发布它发生的行以及异常或错误的详细信息。请编辑这些细节,否则我们可能无法提供帮助。 - Blue
我重新表述了问题。 - b4oshany
6个回答

47
使用Firebase身份验证的客户端SDK时,您只能删除当前已登录的用户帐户。其他任何操作都将构成巨大的安全风险,因为它将允许您的应用程序用户删除彼此的帐户。
Firebase身份验证的管理SDK旨在在受信任的环境中使用,例如您的开发计算机、您控制的服务器或Cloud Functions。因为它们在受信任的环境中运行,所以它们可以执行某些客户端SDK无法执行的操作,例如仅通过知道用户UID即可删除用户帐户
另请参见:

另一种常见的方法是在Firebase数据库中保留一个允许清单/禁止清单,并根据该清单授权用户。请参见如何在Firebase 3.x中禁用注册


2
我认为Firebase Admin SDK仅适用于服务器端而不是客户端,因此无法在ReactJS上使用。 - Carl
2
这是正确的,也是有意为之的。想象一下,如果客户端代码可以在未经身份验证的情况下删除任何用户,那将是一个非常糟糕的安全风险。 - Frank van Puffelen
实际上,可以在前端使用Admin SDK,但不建议这样做,因为这会给你的应用程序带来安全风险,你需要将服务密钥与应用程序一起包含在内,这样就有可能有人从你的代码中获取它,然后以管理员权限向你的Firebase项目发出API请求。 - undefined

22

你肯定不想在应用程序本身中使用 firebase-admin,就像 Ali Haider 建议的那样,因为它需要一个私钥,而你不想将其部署到代码中。

但是,你可以在 Firebase 中创建一个云函数,在你的 Firestore 或实时数据库中删除用户时触发该云函数,并让该云函数使用 firebase-admin 删除用户。 在我的情况下,我在 Firestore 中有一个用户集合,其中 userid 与 Firebase Auth 创建的相同,我保存了额外的用户数据,如姓名和角色等。

如果你像我一样使用 Firestore,则可以执行以下操作。如果你正在使用实时数据库,请查看文档以了解如何为其使用触发器。

  1. 确保Firebase项目已初始化云函数。您的项目目录中应该有一个名为“functions”的文件夹。如果没有,请使用以下命令为您的项目初始化Cloud Functions:firebase init functions

  2. 在Firebase控制台的以下页面上获取服务帐户的私钥:设置>服务帐户。

  3. 将包含私钥的json文件放置在functions\src文件夹中,与index.ts文件并列。

  4. 在index.ts中导出以下函数:

export const removeUser = functions.firestore.document("/users/{uid}")
    .onDelete((snapshot, context) => {        
        const serviceAccount = require('path/to/serviceAccountKey.json');
        admin.initializeApp({
            credential: admin.credential.cert(serviceAccount),
            databaseURL: "https://<DATABASE_NAME>>.firebaseio.com"
        });
        return admin.auth().deleteUser(context.params.uid);
    });

现在使用命令firebase deploy --only functions部署您的云函数。

当在Firebase Firestore中删除用户时,此代码将运行,并从Firebase Auth中删除相应的用户。

了解有关Firebase云函数的更多信息,请参阅https://firebase.google.com/docs/functions/get-started


1
看起来是最好的解决方案!谢谢你! - Włodzimierz Woźniak
1
请注意:Cloud Functions 需要启用 Blaze 计划(按使用量付费)。 - SwiftiSwift

14

只需要像进行身份验证一样应用此代码即可。

var user = firebase.auth().currentUser;

user.delete().then(function() {
  // User deleted.
}).catch(function(error) {
  // An error happened.
});

1
应该是顶部注释。 - theodore hogberg
14
OP要求特定用户,而不是当前登录的用户。 - Mohammad Dohadwala
6
错误的答案,您将删除自己的用户。 - Romanas
看这里,有一个限制条件,你只能在特定情况下删除 - https://dev59.com/91MI5IYBdhLWcg3wRZQs#69207294 - Krishna Shetty

3

使用Javascript API(而非管理SDK)

就像这个答案所指出的那样,为了删除除当前登录用户以外的其他用户,必须创建第二个应用程序。

以下是我的做法:

  async deleteUser (user) {
    // Need to create a second app to delete another user in Firebase auth list than the logged in one.
    // https://dev59.com/61oU5IYBdhLWcg3wYWOx#38013551
    const secondaryApp = firebase.initializeApp(config, 'Secondary')

    if (!user.email || !user.password) {
      return console.warn('Missing email or password to delete the user.')
    }

    await secondaryApp.auth().signInWithEmailAndPassword(user.email, user.password)
      .then(() => {
        const userInFirebaseAuth = secondaryApp.auth().currentUser
        userInFirebaseAuth.delete() // Delete the user in Firebase auth list (has to be logged in).
        secondaryApp.auth().signOut()
        secondaryApp.delete()

        // Then you can delete the user from the users collection if you have one.
      })
  }

如果你把我的密码以明文形式存储,我不想使用你的应用程序。我认为这是一个糟糕的建议。 - Michaja Broertjes
1
@MichajaBroertjes 谁说我是这么做的?代码中没有任何说明。而且函数 secondaryApp.auth().signInWithEmailAndPassword(user.email, user.password) 是 Firebase 内置的,它会使用用户输入的密码。user 参数是包含用户刚刚输入的电子邮件和密码的对象。该应用程序是使用 Vue 构建的。 - antoni

-1

这是Firebase 9+的简单解决方案,如果您想要删除当前用户:

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

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

deleteUser(user).then(() => {
  // User deleted.
}).catch((error) => {
  // An error ocurred
  // ...
});

-5
在我看来,你可以不使用Firebase Admin SDK删除特定用户。你必须存储要管理的帐户的用户名和密码。然后使用一个帐户登录 - 你声明一个管理员帐户。之后只需按照以下步骤操作:使用Firebase auth注销 -> 使用Firebase auth登录要删除的帐户 -> 使用Firebase auth删除该帐户 -> 使用Firebase auth注销 -> 再次使用那个“管理员帐户”登录。希望这个解决方案能帮助你在不使用Firebase Admin SDK的情况下删除帐户。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接