有没有一个简单的方法来删除所有注册用户从消防控制台? 例如,我从我的开发环境中创建了100个用户,现在我想删除所有这些用户。
我是消防员
我们刚刚发布了 Firebase 管理 SDK,它支持管理用例,比如 删除用户帐户而不要求该用户首先登录。
原始答案
目前,FirebaseAuthentication 中没有 API 可以在不要求用户登录的情况下删除用户。我们知道这限制了我们的 API 的可用性,并且正在努力在将来的版本中添加这样的功能。但是像往常一样,我们没有提供特定的时间表来说明这个特性什么时候可用。
目前,你唯一能做的就是:
因为我非常懒于单击 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错误。
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 是 真的很简单和 建议的方式来执行这些任务对您的 Firebase 数据。这个解决方案是使用开发人员控制台的 不像其他临时解决方案。
我刚整合了一个 Node.js 脚本来删除 Firebase 认证中的所有用户。我已经通过删除大约10000个用户对它进行了测试。我只是运行了以下 Node.js 代码。
创建一个新文件夹
npm init sudo npm install firebase-admin --save
现在在这个文件夹中创建一个 index.js文件。
index.js
Generate new Private Key
databaseURL
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 函数。
delete_users.js
node delete_users.js
希望这个能帮上忙。
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)
附言: 如果你不是网页开发者,并且“在工具开发者中执行”对你来说没有任何意义,这里的程序。
在控制台选项卡中,粘贴此代码并按 Enter。
如果语言与您粘贴的代码匹配,帐户将开始被删除。
请尝试此代码获取最新的 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);
下面是另一个可以用作书签工具的脚本
然后只需单击书签即可删除所有用户。当没有更多的用户或者导航离开时,脚本将停止。如果您不使用英文版本,请用相应的文本更新 *Text变量。
*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()
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函数结合起来。注意您可能不希望为真正的数据库创建这种类型的功能。
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 ]
// 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
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 > “刷新按钮”。
我的最新回答是:
因此,如果您打开多个窗口(没有全屏模式) ,并以不同的方式排序,您可以删除所有用户。但有时您会发现一个错误,您删除了一个用户以前。
这就是为什么我添加 times和 elementSize变量,以刷新列表,并继续删除用户
times
elementSize
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转到浏览器控制台
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); }); })();