Is there a way to list all the users using the firebase admin sdk? Documentation only shows getting one user either by uid or email.
The latest firebase-admin sdk
(as of now version 5.4.2
) has listUsers
API that would do that. The example is here.
One thing to add to the example, the nextPageToken
has to be omitted or a valid userid. (IMO, it's not obvious in neither the example or the API doc.)
Update As @Webp says in their answer, there is now an API to list all users in the Admin SDK.
Original answer:
There is no public API to retrieve a list of users from the Firebase Admin SDK.
The typical way to deal with this scenario is to keep a list of the pertinent user information in the Firebase Database. See this original question for more: How do I return a list of users if I use the Firebase simple username & password authentication
You can use auth().listUsers()
method provided in the admin sdk. Detailed example code can be found here.
Firebase Admin SDK Documentation
Its not a good solution, but you can export user data using Firebase CLI and integrate with your application.
auth:export
firebase auth:export account_file --format=file_format
In March 2020, after a lot of fighting with documentation and various posts, i found the following works:
const admin = require("firebase-admin");
const serviceAccount = require('./serviceAccount.json'); // see notes below about this.
const listAllUsers = () => {
const app = admin.initializeApp({
databaseURL: 'https://your-project-name.firebaseio.com',
credential: admin.credential.cert(serviceAccount) <-- see notes below about this
});
app.auth().listUsers(1000) // lists up to 1000 users
.then((listUsersResult) => {
let users = JSON.stringify(listUsersResult);
const date = new Date();
const day = date.getDate();
const month = date.getMonth() + 1;
fs.writeFileSync(__dirname + `/../my-backups/authentication-backup_${day}_${month}_2020.json`, users);
})
.catch(function (error) {
console.log('Oh no! Firebase listUsers Error:', error);
});
}
re serviceAccount.json
This is NOT the same as the usual Firebase config you pass-in when using things like react-firebase or the npm firebase module on front end.
To gain CRUD rights server-side, you seem to need the following:
{
"type": "service_account",
"project_id": "my-project-id",
"private_key_id": "xxxxxxxxxxxxxxxxxxx",
"private_key": "-----BEGIN PRIVATE KEY-----\nMxxxxxxxxxxxxxxzuUA=\n-----END PRIVATE KEY-----\n",
"client_email": "firebase-adminsdk-em4gz@my-project-name-email-thing.iam.gserviceaccount.com",
"client_id": "0000000000000000000",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-em4gz%40my-proj-name.iam.gserviceaccount.com"
}
If you haven't generated one yet, I got mine by going:
Firebase Console => Project Settings => Service Accounts => Generate New Private Key
I got this async version working:
(I haven't thought about the flow of the code so the use of async here may be inefficient in terms of performance... I honestly only use async because I don't like looking at deeply nested promise code)
const firebase = require('firebase-admin');
const credential = require('./credential.json');
firebase.initializeApp({
credential: firebase.credential.cert(credential)
});
let users = [];
async function getAllUsers(pageToken) {
const results = await firebase.auth().listUsers(1000, pageToken);
for (let i = 0; i < results.users.length; i++) {
const user = results.users[i];
const {uid, email} = user;
users.push({uid, email});
}
if (results.pageToken) {
getAllUsers(results.pageToken);
}
};
(async () => {
await getAllUsers();
console.log(users);
})();
await
keyword has to be used within an async function: anthonychu.ca/post/async-await-typescript-nodejs –
Reasoning As described in the official doc. Firebase Documentation the method to get list of users is mentioned already but it only lists max of 1000 users at a time. But if users are more than 1000 we need to use our own logic to get those remaining users with pagetokens/pagination.
Here I have tried to use that method in recursive manner to get full list of users in firebase database.
async getAllUsers(nextPageToken?: String): Promise<any[]> {
// List batch of users can be max 1000 at a time.
var _users_list = [];
await this.firebaseAdmin.auth()
.listUsers(100, nextPageToken)
.then(async (listUsersResult) =>
_users_list = listUsersResult.users;
console.log("list user page token =>", listUsersResult.pageToken);
if (listUsersResult.pageToken) {
// List next batch of users.
const temp_list = await this.getAllUsers(listUsersResult.pageToken);
if (temp_list.length > 0) { _users_list = _users_list.concat(temp_list); }
}
})
.catch((error) => {
console.log('Error listing users:', error);
});
return _users_list
};
This function returns the list of all users registered in firebase auth.
Here I have used batch of length 100 just to check if the function is working properly, You can change it up to 1000 at max, after thousand it throws Exceptions as described in firebase documentation
public async getAllUsers(): Promise<UserRecord[]> {
const records: UserRecord[] = [];
const listAllUsers = async (maxResults = 1000, nextPageToken?: string): Promise<void> => {
const listAllUsersResult = await firebase.auth().listUsers(maxResults, nextPageToken);
listAllUsersResult.users.forEach(userRecord => {
records.push(userRecord);
});
if (listAllUsersResult.pageToken) {
await listAllUsers(maxResults, listAllUsersResult.pageToken);
}
};
await listAllUsers();
return records;
}
You can also use recursion to return all user records (UserRecord[]
).
import * as FAdmin from 'firebase-admin/lib/auth'
export const findUnusedUsers = functions.https.onCall((data, context) => {
return listAllUsers().then(allUsers => {
return allUsers
})
})
const listAllUsers = (nextPageToken?: string, accumulatorUsers: FAdmin.auth.UserRecord[] = []): Promise<FAdmin.auth.UserRecord[]> => {
return admin.auth().listUsers(1000, nextPageToken)
.then(function(listUsersResult) {
const users = [...accumulatorUsers, ...listUsersResult.users]
if (listUsersResult.pageToken) {
return listAllUsers(listUsersResult.pageToken, users)
} else {
return users
}
})
}
© 2022 - 2024 — McMap. All rights reserved.