Is there an easy way to delete all registered users from firebase console? For example, I created a hundred users from my development environment, and now I want to delete all of them.
21 Answers
As in updated answer, you can probably use firebase admin tools now, but if you don't want – here is a bit more solid javascript to remove users in the 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)
Just run it in developer tools
-
4This works, however make sure to have the tab open not switch to a different one while it's running – KrauseFx Apr 08 '17 at 23:36
-
3Worked for me too. Thanks. It's sad this has to be the workaround. – Drew Szurko Apr 14 '17 at 01:11
-
1Yes! Thank you. The delay was needed apparently. – brs14ku Jun 19 '17 at 04:25
-
17You deserve a Nobel prize for this answer! – Yassine ElBadaoui Dec 08 '17 at 15:16
-
3I didn't even know that I could run Javascript in the console. Lessons learned. Learn the basics of other things too. – Rethinavel Nov 10 '18 at 11:38
-
3This script is better than the others! – Nguyen Thanh Apr 19 '19 at 10:44
-
1Thanks! you saved 342 clicks and 228 mouse moves – Soorya Dec 26 '19 at 07:11
-
Confirmed this is still working in Jan. 2020. I was running anonymous users for about about a year, so now I'm using alternate browser to auto-click and delete 13,000 of them, 250 per page at a time (250 per page). THANKS! – Daniel Fowler Jan 07 '20 at 15:42
-
When trying this script, set "Rows per page" to max and run. – Ayyappa May 07 '20 at 11:02
-
why cant you tab away? – SuperUberDuper May 13 '20 at 14:02
-
Doesn't work for me. Just says 'interval cleared' – melchoir55 Dec 18 '20 at 21:21
-
I would suppose something changed in the UI of Firebase and script needs some updating. I wouldn't risk deleting my users at the moment, so if anyone will adjust the script for the changes, send me a message and I will update the answer. – AAverin Dec 19 '20 at 09:58
Because I'm pretty lazy at clicking buttons and elements in the UI, I set up a small client script:
$('[aria-label="Delete account"]').click()
setTimeout(function () {
$(".md-raised:contains(Delete)").click()
}, 1000);
You may need to run it multiple times, but it is much better than wasting the time clicking things on the screen manually.
- 93,552
- 74
- 254
- 426
-
Thanks a lot...works great..saves me 2 clicks and moving the mouse around :) – krv Oct 27 '16 at 04:37
-
1
-
@LuisMejíaF. I expected it to be useful when posting the answer :) Always, automate the stuff when there's something repetitive to do :-) – Ionică Bizău Feb 01 '17 at 17:55
-
-
-
-
3@mjpablo23 Open the browser developer tools (Right click on the page and `Inspect` or `Inspect Element`), then go to the `Console` tab and paste the code and press the *return* / *enter* key. – Ionică Bizău Apr 01 '17 at 19:30
-
what do I right click on? I'm on the Firebase->Authentication page in the Firebase console. – mjpablo23 Apr 01 '17 at 21:28
-
Here is my bicycle:
setInterval(() => {
$('[aria-label="Delete account"]').first().click()
setTimeout(()=>{
$(".md-raised:contains(Delete)").click()
}, 100)
}, 2000);
designed to avoid calling delete
endpoint very often, since google fails with 404
error.
- 1,215
- 12
- 16
-
haha, thanks @AndroidRuntimeException , now someone should release an international version (seeing all those different languages above) and a version with official API, and this post will become ideal, lol – Eugene Hauptmann Aug 18 '18 at 05:00
-
-
3
-
1
-
That's cool @Murtuza ideally it would be linked to the event handler when XHR requests are finished. – Eugene Hauptmann Sep 30 '19 at 19:53
-
1I love this solution! I'm adding an if statement to count for the need to go to the next page though. – Chris Feb 16 '20 at 18:18
-
hey @Chris, great to hear! Feel free to share your solution. Let's make firebase easier for us all :) – Eugene Hauptmann Feb 29 '20 at 20:50
-
1
firebaser here
Update 2016-11-08 original answer below
We just released the Firebase Admin SDK, which supports administrative use-cases, such as deleting a user account without requiring that user to sign in first.
original answer
There is currently no API in Firebase Authentication to delete a user without requiring that user to sign in. We know this limits the usability of our API and are working to add such functionality in a future release. But as usual, we don't provide specific timelines for when the feature will be available.
For the moment your only work arounds are to:
- sign in as each test user in the app and delete the user from there
- delete each user in turn from the Firebase Console
- 418,229
- 62
- 649
- 645
-
21Can you please consider removing the 'Are you sure prompt' in the Firebase Console if you 'Shift' + click 'Delete account'. This would mimic the behaviour in the database and would significantly speed things up. – DrZaphod Oct 13 '16 at 10:02
-
Can I "sign in as each test user" from appengine , without browser? Can I delete users from app engine directly somehow or via some web services? – makkasi Nov 01 '16 at 13:35
-
in the NodeJs firebase-admin SDK is there no way to get all users then for each user `admin.auth().deleteUser(uid);` – Snewedon Nov 08 '16 at 03:53
-
@Frank van Puffelen I see there is not python admin SDK. Is there some way to use the nodeJS admin SDK inside python. – makkasi Feb 24 '17 at 08:23
-
Am glad to know this is now possible via firebase admin sdk. Would be cool to know if these can also be uploaded and used as google https functions? TIA! – raiser00 Dec 27 '17 at 15:43
Fully working solution using Firebase Admin SDK
Using the Firebase Admin SDK is really easy and the recommended way to perform such tasks on your Firebase data. This solution is unlike the other makeshift solutions using the developer console.
I just put together a Node.js script to delete all users in your Firebase authentication. I have already tested it by deleting ~10000 users. I simply ran the following Node.js code.
To setup Firebase Admin SDK
Create a new folder. Run the following in terminal
npm init
sudo npm install firebase-admin --save
Now create an index.js
file in this folder.
Steps to follow:
- Go to your Firebase project -> Project Settings -> Service Accounts.
- Click on
Generate new Private Key
to download the JSON file. Copy the path to JSON file and replace it in the code below in the path to service accounts private key json file. - Also, copy the
databaseURL
from the settings page. Replace it in the code. - Copy and paste the code in
index.js
. - Run in terminal
node index.js
. Watch the mayhem!
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();
- 2,386
- 2
- 13
- 25
-
1This worked for me. I'm blocked right now tho, api didn't let me delete more about 8,000 users in – Jorsh Aug 27 '19 at 00:20
-
Glad it worked. However, I did not face any blocking or restrictions when I tried it. – Sunit Gautam Aug 27 '19 at 05:59
-
-
Nice. Here it complained about reaching the limit after ~100 removals, but just executed it again to finishing removing all. I recommend using .gitignore on the cred.json file. – Henrique Bruno Feb 04 '21 at 23:21
For the new Firebase update (07.05.2021)
Try this code for the latest Firebase update. Open the console, paste this code and hit enter!!!
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)
- 517
- 4
- 18
-
3This works great, thanks! Just note: if there's an anonymous account in the list, change index in second 'getElementsByClassName' from 2 to 1. Also you can set shorter interval, i used 500. – the korovay Apr 13 '21 at 12:12
-
2
-
-
@b.john - Go to the auth page in your firebase console - Open the dev console in your browser - Paste this code and hit enter – Yaman KATBY May 22 '21 at 11:00
-
I made it working by changing 2nd command's index to 1, not 2 => document.getElementsByClassName('mat-focus-indicator mat-menu-item ng-star-inserted')[1].click() – Yunus Yurtturk May 27 '21 at 15:20
Slightly increased your helper script.
German firebase site version:
$('[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);
}
For the english version just replace the text. This way you can delete 20 or more users once executed.
- 324
- 3
- 10
-
Is this right so far? "Löschen" = "Delete" "Konto löschen" = "Delete account" "Nutzermenü öffnen" = ? – Aldasa Jan 14 '17 at 12:38
-
200 ms was short in my case. Set to 1000 - 1500 ms and it works! – Sebastian Ortmann Jul 20 '18 at 00:39
-
Used this code successfully on 11/16/2020:
setInterval(function () {
$('[aria-label="View more options"]')[0].click()
document.querySelectorAll('.mat-menu-item')[2].click()
document.querySelector('.confirm-button').click()
}, 1000);
-
If you want to get possible rep for your answer then provide substantial more info to boos quality of your answer. 15 answer were before you... – ZF007 Nov 16 '20 at 21:43
-
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);
Try this one. It's an update to @www.eugenehp.tk answer above that takes into account the need to refresh the page if you have more than one page of entries.
- 915
- 13
- 20
Well, I used this script to delete all users at once in Firebase console:
$('[aria-label="Delete account"]').each(function() {
$(this).click();
$('[ng-click="controller.submit()"]').click()
})
https://console.firebase.google.com/project/YOUR_PROJECT_NAME/authentication/users
- 240
- 3
- 14
Russian version
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)
- 11
- 1
A solution that worked for me was to create a separate file and import my firebase-admin and simply run the following:
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();
The concept here is that we want to retrieve all the users from our user auth table, then cycle throw and delete them one at a time using the deleteUser admin auth method.
In the terminal, I simply used node to call the function in the file (so let's say the filename is delete_users.js
, I just called node delete_users.js
and the listUsers function was invoked.
Hope this helps.
- 299
- 3
- 11
-
Thanks, but a few things I had to go add on. Required the addition of firebase-functions and also a private key to give the script credentials to run. Followed these steps: https://firebase.google.com/docs/admin/setup – howdoyouturnthison Nov 30 '19 at 15:33
French version,
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)
PS: if you are not web developer and "Execute in tools developer" means nothing to you, here the procedure.
- Open your firebase authentication/users page with Chrome
- Press control + shif+ J
In the console tab, paste this code and press enter.
If the language matched with the code your paste, account will start to be deleted.
Just execute the below script on the console and it will delete all users at once.
$('.edit-account-button').click();
$('.mat-menu-content button:last-child').click()
$('.fire-dialog-actions .confirm-button').click()
- 61
- 5
This might be helpful to some. If you have access to the firebase user console - just save the page as an html and use the following to delete users with node. need to setup 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);
});
I would recommend doing a dry run of the html parsing logic once on the page using browser by just running this and confirming that only user ids are displayed in the result. In my case this returned all UIDs
$('.a12n-user-uid .fb-table-cell-wrapper').each(function() {
console.log($(this).text());
});
I used it
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")
- 1,015
- 2
- 8
- 7
I tried all the previous, none worked, so I created one for my needs:
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);
- 167
- 1
- 4
Here's another script that can be used as a bookmarklet. Simply
- create a new bookmark (Ctrl-D)
- select "more"'
- paste the script into the URL input
You can then just click the bookmark to delete all users. The script will stop when there's no more users or you navigate away. If you're not using the english version, update the *Text
variables with the corresponding 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();
})();
- 12,175
- 4
- 50
- 54
if u have anonymous accounts
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)
Just worked here (2021)
var times = 0;
setInterval(() => {
$('.edit-account-button').first().click()
setTimeout(()=>{
$(".mat-button-wrapper:contains(Excluir)").click()
}, 200)
setTimeout(()=>{
$(".mat-menu-item:contains(Excluir)").click()
}, 200)
setTimeout(()=>{
$(".mat-button-wrapper:contains(Excluir)").click()
}, 200)
times++;
console.log(times)
if(times == 150) {
console.log("ATUALIZANDO!!!")
setTimeout(()=>{
$('[aria-label="Atualizar"]').click();
times = 0 ;
}, 200)
}
}, 1000);
with a reload each 150 times, u need just to put in 250
- 1
- 1
- 1
Try this,
var elements = [];
$('.a12n-users-table').find('tr').each(function(r){
$(this).find('td.table-row-actions').each(function(tds) {
$(this).find('button').each(function(x){
if($(this).attr('aria-label')=="Delete account"){
elements.push($(this));
}
});
});
});
var index = 0;
function deleteUser(){
index++;
elements[index].click();
$('.fb-dialog-actions').find('.md-warn').click();
setTimeout(deleteUser, 5000);
}
deleteUser();
- 791
- 8
- 19