从 Firebase 认证控制台删除所有用户

有没有一个简单的方法来删除所有注册用户从消防控制台? 例如,我从我的开发环境中创建了100个用户,现在我想删除所有这些用户。

46515 次浏览

我是消防员

更新2016-11-08 原答案如下

我们刚刚发布了 Firebase 管理 SDK,它支持管理用例,比如 删除用户帐户而不要求该用户首先登录

原始答案

目前,FirebaseAuthentication 中没有 API 可以在不要求用户登录的情况下删除用户。我们知道这限制了我们的 API 的可用性,并且正在努力在将来的版本中添加这样的功能。但是像往常一样,我们没有提供特定的时间表来说明这个特性什么时候可用。

目前,你唯一能做的就是:

  • 作为应用程序中的每个测试用户登录并从中删除用户
  • 依次从 Firebase 控制台删除每个用户

因为我非常懒于单击 UI 中的按钮和元素,所以我设置了一个小客户端脚本:

$('[aria-label="Delete account"]').click()
setTimeout(function () {
$(".md-raised:contains(Delete)").click()
}, 1000);

您可能需要多次运行它,但是这比手动点击屏幕上的内容要好得多。

稍微增加了你的帮助脚本。

德国消防基地网站版本:

$('[aria-label="Nutzermenü öffnen"]').click();
$('[aria-label="Konto löschen"]').click();
for (i = 0; i < 20; i++) {
setTimeout(() => {
$('.md-raised:contains(Löschen)').click();
}, i * 200);
}

对于英文版只是替换文本。 这样一旦执行,您就可以删除20个或更多的用户。

我使用这个脚本在 Firebase 控制台中一次性删除所有用户:

$('[aria-label="Delete account"]').each(function() {
$(this).click();
$('[ng-click="controller.submit()"]').click()
})

Https://console.firebase.google.com/project/your_project_name/authentication/users

这可能对某些人有帮助。 如果你可以访问 firebase 用户控制台-只需要将页面保存为 html 并使用以下命令删除带有节点的用户。需要设置 Firebase-admin

let fs = require('fs'),
admin = require('firebase-admin'),
cheerio = require('cheerio');


// initialize firebase admin here
admin.initializeApp({
credential: admin.credential.cert('path/to/serviceAccountKey.json'),
databaseURL: 'https://<DATABASE_NAME>.firebaseio.com'
});


// use cheerio to load the html file you downloaded
$ = cheerio.load(fs.readFileSync('./yourfirebaseconsole.html'));
$('.a12n-user-uid .fb-table-cell-wrapper').each(function() {
admin.auth().deleteUser($(this).text());
}).then(() => {
console.log('successfully delete user');
}).catch((error) => {
console.log('error occurred ', error);
});

我建议使用浏览器在页面上运行一次 html 解析逻辑,只需运行该逻辑并确认结果中只显示用户 ID 即可。在我的例子中,它返回了所有的 UID

$('.a12n-user-uid .fb-table-cell-wrapper').each(function() {
console.log($(this).text());
});

在更新的回答中,你可能现在就可以使用 firebase 管理工具,但是如果你不想使用的话——这里有一个更加可靠的 javascript 来删除 web 上的用户:

var intervalId;


var clearFunction = function() {
var size = $('[aria-label="Delete account"]').size()
if (size == 0) {
console.log("interval cleared")
clearInterval(intervalId)
return
}
var index = Math.floor(Math.random() * size)
$('[aria-label="Delete account"]')[index].click();
setTimeout(function () {
$(".md-raised:contains(Delete)").click()
}, 1000);
};


intervalId = setInterval(clearFunction, 300)

只要在开发人员工具中运行它

俄语版的

var intervalId;


var clearFunction = function() {
if ($('[aria-label="Удаление аккаунта"]').size() == 0) {
console.log("interval cleared")
clearInterval(intervalId)
return
}
$('[aria-label="Удаление аккаунта"]')[0].click();
setTimeout(function () {
$('[ng-click="controller.submit()"]').click()
}, 1000);
};


intervalId = setInterval(clearFunction, 3000)

setInterval(() => {
$('[aria-label="Delete account"]').first().click()
setTimeout(()=>{
$(".md-raised:contains(Delete)").click()
}, 100)
}, 2000);

设计,以避免调用 delete端点非常频繁,因为谷歌失败与 404错误。

我用了

var openMenuItemForFirstUser = function () {
const menuItem = $('[ng-click="controller.deleteUser()"]')
if (menuItem.size()) {
menuItem[0].classList.add("deletingThisUser")
menuItem[0].click();
setTimeout(deleteUser, 10, 0)
} else {
console.log("No users found...")
}
};


var deleteUser = function (t) {
const confirmButton = $('[ng-click="controller.submit()"]')
if (confirmButton.size()) {
console.log("deleting user")
confirmButton[0].click()
setTimeout(waitForDeletion, 10, 0)
} else {
if (t > 500) console.log("fail trying delete user")
else setTimeout(deleteUser, 10, parseInt(t) + 1)
}
}


var waitForDeletion = function (t) {
const deletingThisUser = $('.deletingThisUser')
if (deletingThisUser.size()) {
if (t > 500) console.log("fail wait for deletion")
else setTimeout(waitForDeletion, 10, parseInt(t) + 1)
} else {
setTimeout(openMenuItemForFirstUser, 10)
}
}


setTimeout(openMenuItemForFirstUser, 1000)
console.log("Deleting all users... Press F5 to cancel it")


使用 FirebaseAdminSDK 完全工作的解决方案

使用 FirebaseAdminSDK 是 真的很简单建议的方式来执行这些任务对您的 Firebase 数据。这个解决方案是使用开发人员控制台的 不像其他临时解决方案。

我刚整合了一个 Node.js 脚本来删除 Firebase 认证中的所有用户。我已经通过删除大约10000个用户对它进行了测试。我只是运行了以下 Node.js 代码。

安装 Firebase 管理 SDK

创建一个新文件夹

npm init
sudo npm install firebase-admin --save

现在在这个文件夹中创建一个 index.js文件。

以下步骤:

  • 进入你的 Firebase 项目-> 项目设置-> 服务帐户。
  • 单击 Generate new Private Key下载 JSON 文件。将路径复制到 JSON 文件,并在下面的代码中将其替换到服务帐户私钥 JSON 文件的路径中。
  • 另外,从设置页面复制 databaseURL。在代码中替换它。
  • 复制并粘贴 index.js中的代码。
  • 进入 node index.js航站楼,小心混乱!
var admin = require('firebase-admin');


var serviceAccount = require("/path/to/service/accounts/private/key/json/file");


admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "/url/to/your/database"
});


function deleteUser(uid) {
admin.auth().deleteUser(uid)
.then(function() {
console.log('Successfully deleted user', uid);
})
.catch(function(error) {
console.log('Error deleting user:', error);
});
}


function getAllUsers(nextPageToken) {
admin.auth().listUsers(100, nextPageToken)
.then(function(listUsersResult) {
listUsersResult.users.forEach(function(userRecord) {
uid = userRecord.toJSON().uid;
deleteUser(uid);
});
if (listUsersResult.pageToken) {
getAllUsers(listUsersResult.pageToken);
}
})
.catch(function(error) {
console.log('Error listing users:', error);
});
}


getAllUsers();

一个对我有效的解决方案是创建一个单独的文件并导入我的 firebase-admin,然后简单地运行以下命令:

const admin = require('./firebase_admin');


const listAllUsers = () => {
console.log('list all users');
// List batch of users, 1000 at a time.
admin.auth().listUsers(1000)
.then((listUsersResult) => {
listUsersResult.users.forEach((userRecord) => {
const user = userRecord.toJSON();
admin
.auth()
.deleteUser(user.uid)
.then(() => {
console.log('successfully deleted user');
})
.catch((err) => {
console.error('error deleting user: ', err);
});
});
if (listUsersResult.pageToken) {
// List next batch of users.
listAllUsers(listUsersResult.pageToken);
}
})
.catch((error) => {
console.log('Error listing users:', error);
});
};
// Start listing users from the beginning, 1000 at a time.
listAllUsers();

这里的概念是,我们希望从用户认证表中检索所有用户,然后使用 delete teUser admin auth 方法循环抛出和删除一个用户。

在终端中,我只是使用 node 调用文件中的函数(假设文件名是 delete_users.js,我只调用了 node delete_users.js,并调用了 listUsers 函数。

希望这个能帮上忙。

setInterval(() => {
if ($('[aria-label="Delete account"]').length > 0) {
$('[aria-label="Delete account"]').first().click()
setTimeout(()=>{
$(".md-raised:contains(Delete)").click()
}, 100)
} else {
$('[aria-label="Reload"]').first().click()
}
}, 2000);

试试这个。是@www 的更新。上面的 eugenehp.tk 答案考虑到如果有多个页面的条目需要刷新页面。

法文版,

var intervalId;


var clearFunction = function() {
if ($('[aria-label="Supprimer le compte"]').size() == 0) {
console.log("interval cleared")
clearInterval(intervalId)
return
}
$('[aria-label="Supprimer le compte"]')[0].click();
setTimeout(function () {
$(".md-raised:contains(Supprimer)").click()
}, 1000);
};


intervalId = setInterval(clearFunction, 3000)

附言: 如果你不是网页开发者,并且“在工具开发者中执行”对你来说没有任何意义,这里的程序。

  • 用 Chrome 打开你的 firebase 认证/用户页面
  • 按下控制键 + 移位键 + J 键
  • 在控制台选项卡中,粘贴此代码并按 Enter。

  • 如果语言与您粘贴的代码匹配,帐户将开始被删除。

新的 Firebase 更新

请尝试此代码获取最新的 Firebase 更新。 打开控制台,粘贴此代码并按回车键! ! !

setInterval(() => {
document.getElementsByClassName('edit-account-button mat-focus-indicator mat-menu-trigger mat-icon-button mat-button-base')[0].click()
let deleteButtonPosition = document.getElementsByClassName('mat-focus-indicator mat-menu-item ng-star-inserted').length - 1
document.getElementsByClassName('mat-focus-indicator mat-menu-item ng-star-inserted')[deleteButtonPosition].click()
document.getElementsByClassName('confirm-button mat-focus-indicator mat-raised-button mat-button-base mat-warn')[0].click()
}, 1000)

在2020年11月16日成功地使用了这个代码:

setInterval(function () {
$('[aria-label="View more options"]')[0].click()
document.querySelectorAll('.mat-menu-item')[2].click()
document.querySelector('.confirm-button').click()
}, 1000);

我尝试了所有以前的方法,没有一个奏效,所以我根据自己的需要创建了一个:

setInterval(() => {


if ($('[aria-label="View more options"]').length > 0) {


$('[aria-label="View more options"]')[0].click()


if ($('[role="menuitem"]').length > 0) {


$('[role="menuitem"]')[1].click()


if ($('[class="confirm-button mat-focus-indicator mat-raised-button mat-button-base mat-warn"]').length > 0) {


$('[class="confirm-button mat-focus-indicator mat-raised-button mat-button-base mat-warn"]').click()
}
}
}
}, 500);

下面是另一个可以用作书签工具的脚本

  1. 创建一个新书签(Ctrl-D)
  2. 选择「更多」
  3. 将脚本粘贴到 URL 输入中

然后只需单击书签即可删除所有用户。当没有更多的用户或者导航离开时,脚本将停止。如果您不使用英文版本,请用相应的文本更新 *Text变量。

javascript: (function () {
const deleteText = 'Delete account';
const deleteConfirmationText = 'Delete';


const editSelector = '.edit-account-button';
const deleteSelector = `button:contains(${deleteText})`;
const deleteConfirmationSelector = `button span:contains(${deleteConfirmationText})`;
const waitForAnimation = 350;


const deleteUsers = () => {
const editAccountButton = $(editSelector).first();


if (!editAccountButton.size()) {
console.log('Delete complete.');
return;
}


editAccountButton.first().click();
setTimeout(() => {
$(deleteSelector).first().click();
setTimeout(() => {
$(deleteConfirmationSelector).first().click();
setTimeout(() => {
deleteUsers();
}, waitForAnimation * 1.5);
}, waitForAnimation);
}, waitForAnimation);
};


deleteUsers();
})();

如果你有匿名账户

setInterval(() => {
document.getElementsByClassName('edit-account-button mat-focus-indicator mat-menu-trigger mat-icon-button mat-button-base')[0].click()
document.getElementsByClassName('mat-focus-indicator mat-menu-item ng-star-inserted')[document.getElementsByClassName('mat-focus-indicator mat-menu-item ng-star-inserted').length === 3 ? 2 : 1].click()
document.getElementsByClassName('confirm-button mat-focus-indicator mat-raised-button mat-button-base mat-warn')[0].click()
}, 1000)

只需在控制台上执行下面的脚本,它就会立即删除所有用户。

$('.edit-account-button').click();


$('.mat-menu-content button:last-child').click()


$('.fire-dialog-actions .confirm-button').click()


更新2021年工作答案

const interval = setInterval(() => {
if ($('.edit-account-button').length === 0) {
clearInterval(interval)
} else {
$('.edit-account-button').first().click()
$('button:contains("Delete account")').click()
$('.confirm-button').click()
}
}, 1000)

Https://gist.github.com/cupcakearmy/8c314b891e6958f26374c0205bac85e9

在我的项目中,我将 firebaseAdmin 连接到一个模拟器进行测试。为了在每次测试前清除数据库,我将 listUsers函数和 deleteUser函数结合起来。注意您可能不希望为真正的数据库创建这种类型的功能。

我的代码是这样的。

import * as Bluebird from "bluebird"


function clearAllUsers() {
return Promise.resolve()
.then(() => admin.auth().listUsers())
.then((response) => response.users)
.then((users) =>
Bluebird.map(users, (user: { uid: string }) =>
admin.auth().deleteUser(user.uid),
),
);
}

但是您也可以使用异步等待来完成同样的事情

import * as Bluebird from "bluebird"
async function clearAllUsers() {
const usersResponse = await admin.auth().listUsers();
const users = usersResponse.users;
return await Bluebird.map(users, (user: { uid: string }) =>
admin.auth().deleteUser(user.uid),
);
}


另外,如果您碰巧使用了模拟器进行测试,那么该模拟器的用户界面会附带一个 delete all 按钮。看(这里)[ https://imgur.com/3xil86i ]

简单删除所有用户-ESM

// delete.ts or delete.mjs


import admin from 'firebase-admin';
import cred from './credentials.json';
let firebaseApp = admin.initializeApp({
credential: admin.credential.cert(cred as admin.ServiceAccount)
});
const listAllUsers = (nextPageToken?: string) => {
// List batch of users, 1000 at a time.
admin
.auth()
.listUsers(1000, nextPageToken)
.then(async (listUsersResult) => {
await admin.auth().deleteUsers(listUsersResult.users.map((u) => u.uid));
if (listUsersResult.pageToken) {
// List next batch of users.
listAllUsers(listUsersResult.pageToken);
}
})
.catch((error) => {
console.log('Error listing users:', error);
});
};
listAllUsers();

现在工作17.09.2021

转到您的火力基地控制台,单击检查元素,选择控制台,并粘贴这个代码。

setInterval(() => {
document.getElementsByClassName('edit-account-button mat-focus-indicator mat-menu-trigger mat-icon-button mat-button-base')[0].click()
document.getElementsByClassName('mat-focus-indicator mat-menu-item ng-star-inserted')[2].click()
document.getElementsByClassName('confirm-button mat-focus-indicator mat-raised-button mat-button-base mat-warn')[0].click()
}, 1000)

对于身份验证类型: 如果您在第二行通过邮件 id 使用[2]进行身份验证, 如果在第二行使用移动认证 use1

enter image description here

在2021年10月10日测试

这将点击上下文菜单中的最后一个按钮,它总是删除按钮,所以它可以在所有的帐户类型上工作
setInterval(() => {
document.getElementsByClassName('edit-account-button mat-focus-indicator mat-menu-trigger mat-icon-button mat-button-base')[0].click()
var buttons = document.getElementsByClassName('mat-focus-indicator mat-menu-item ng-star-inserted');
buttons.item(buttons.length - 1).click();
document.getElementsByClassName('confirm-button mat-focus-indicator mat-raised-button mat-button-base mat-warn')[0].click()
}, 1000);

2022/02/19工作

setInterval(() => {
$('[mattooltip="View more options"]').first().click()
setTimeout(()=>{
$(".mat-focus-indicator:contains(Delete)").click()
setTimeout(()=>{
$(".mat-warn").click()
}, 100)
}, 100)
}, 2000);

更新03/2022工作状态(加载下一记录页)

setInterval(() => {
var RecordsCount = document.getElementsByClassName('edit-account-button mat-focus-indicator mat-menu-trigger mat-icon-button mat-button-base').length;
if (RecordsCount>0)
{
document.getElementsByClassName('edit-account-button mat-focus-indicator mat-menu-trigger mat-icon-button mat-button-base')[0].click()
let deleteButtonPosition = document.getElementsByClassName('mat-focus-indicator mat-menu-item ng-star-inserted').length - 1
document.getElementsByClassName('mat-focus-indicator mat-menu-item ng-star-inserted')[deleteButtonPosition].click()
document.getElementsByClassName('confirm-button mat-focus-indicator mat-raised-button mat-button-base mat-warn')[0].click()
}
else
{
//reload more records
$('[aria-label="Reload"]').first().click();
}
}, 800);

我想改进 Yaman-katby 回答,因为我不想每次清单为空时都按 < strong > “刷新按钮”


我的最新回答是:

因此,如果您打开多个窗口(没有全屏模式) ,并以不同的方式排序,您可以删除所有用户。但有时您会发现一个错误,您删除了一个用户以前。

这就是为什么我添加 timeselementSize变量,以刷新列表,并继续删除用户

let times=0;
let elementSize=0;
setInterval(() => {
if( (document.getElementsByClassName('no-user-text ng-star-inserted').length > 0) || ( elementSize == document.getElementsByClassName('edit-account-button mat-focus-indicator mat-menu-trigger mat-icon-button mat-button-base').length && times == 3 ) || times == 50 ) {
times=0;
elementSize=0;
document.querySelectorAll('.mat-focus-indicator.mat-mdc-tooltip-trigger.mat-icon-button.mat-button-base[data-test-id="reload-user-button"]')[0].click()
} else {
document.getElementsByClassName('edit-account-button mat-focus-indicator mat-menu-trigger mat-icon-button mat-button-base')[0].click();
let deleteButtonPosition = document.getElementsByClassName('mat-focus-indicator mat-menu-item ng-star-inserted').length - 1;
document.getElementsByClassName('mat-focus-indicator mat-menu-item ng-star-inserted')[deleteButtonPosition].click();
document.getElementsByClassName('confirm-button mat-focus-indicator mat-raised-button mat-button-base mat-warn')[0].click();
elementSize = document.getElementsByClassName('edit-account-button mat-focus-indicator mat-menu-trigger mat-icon-button mat-button-base').length;
times++;
}
}, 1000)

刚刚创建了一个脚本,当 Firebase Authentication 窗口打开时运行到控制台。 步骤1 : 转到 Firebase 项目的验证选项卡

步骤2 : 按 Ctrl + Shift + i转到浏览器控制台

步骤3 : 复制下面的代码并将其粘贴到控制台。




(function delScript() {
const allRowNodes = document.querySelectorAll("tbody tr");
if (!allRowNodes || !allRowNodes.length) {
console.log("No Accounts to delete 🙄😐");
return null;
}
allRowNodes.forEach((curRowNode, idx) => {
setTimeout(() => {
curRowNode.querySelector(".edit-account-button").click();
setTimeout(() => {
document.querySelector("button.mat-menu-item:nth-child(3)").click();
setTimeout(() => {
document
.querySelector("fire-dialog-actions button:nth-child(2)")
.click();
setTimeout(() => {
const backdrop = document.querySelector(
".cdk-overlay-backdrop-showing"
);
backdrop.click();
}, 1200);
}, idx * 1600);
}, idx * 800);
}, idx * 800);
});
})();