如何导出 Firebase Authentication 用户
Firebase Authentication 的用户(Users)标签页列出了项目中的每个账号,却无法把它们下载下来:它唯一的菜单里只有密码哈希参数。要把用户导出为文件,有三种方法。哪一种合适,取决于文件的用途:是用来查看、分享或发邮件的名单,还是要迁移到另一个项目。
更新于 2026年10月7日。 方法 1 中的扩展程序 Firexport 是我们开发的。方法 2 和 3 不需要它。
简短回答
| 1. 控制台 + 扩展程序 | 2. Firebase CLI | 3. Admin SDK 脚本 | |
|---|---|---|---|
| 准备工作 | 安装一个 Chrome 扩展程序 | Node.js 和 Firebase CLI | Node.js 和 Google Cloud 凭据 |
| 格式 | 带标题行的 CSV,或 JSON | 不带标题行的 CSV,或 JSON | 带标题行的 CSV(或你的代码写出的任何格式) |
| 时间 | 控制台显示的日期(Advanced 为 ISO 8601) | Unix 时间戳(毫秒) | ISO 8601 |
| 自定义声明 | Advanced 才有 | 包含 | 包含 |
| 密码哈希 | 从不读取 | 包含(需 Editor 或 Owner 角色) | 不包含 |
1. 用 Firexport 从 Firebase 控制台导出
在 Firebase 控制台中,Authentication > 用户(Users)以表格形式一次一页地显示你的用户,却没有任何下载它们的办法。Firexport 是一款免费的 Chrome 扩展程序,会在这个表格上添加一个“导出”按钮。
- 从 Chrome 应用商店安装 Firexport。
- 在 Firebase 控制台中打开 Authentication,进入用户(Users)标签页。
- 点击添加用户(Add user)右侧的导出。Firexport 会遍历表格的每一页,下载一个 CSV 文件。要导出 JSON,打开按钮旁的 ⋮ 菜单并选择导出为 JSON。

文件中会包含:
- 在免费版中,每个用户一行,包含
uid、identifier、disabled、providers、creationTime和lastSignInTime,也就是控制台显示的那张表格。日期采用控制台的格式,不含时间;提供方是 Email 或 Google 这样的名称。 - 付费方案 Firexport Advanced 会以 Admin SDK 的字段名写出每个用户的完整记录:
email、emailVerified、displayName、phoneNumber、photoURL、providerData、customClaims、multiFactor,以及 ISO 8601(UTC)格式的创建时间、登录时间和令牌时间。 - 无论控制台使用什么语言,列名都是英文,因此每次导出的列都相同。
Firexport 从不读取密码哈希,你的用户数据也始终留在浏览器中:文件在浏览器内生成,除了你的下载内容之外不会去往任何地方。无需设置服务账号密钥或 CLI,因为它在你已登录的控制台会话中运行。它可在 Chrome 及其他基于 Chromium 的浏览器中运行。
一次查看一个用户
要查看单个用户,把鼠标悬停在该用户所在的行上。行操作最前面的信息图标会打开一张卡片,显示完整记录:显示名称、电子邮件已验证、提供方、登录和令牌时间、自定义声明以及第二重验证。卡片上的复制图标会把该用户以 JSON 形式复制到剪贴板。这两项功能都是免费的。

不用 CLI、不用服务账号密钥,直接从控制台导出你的 Firebase 用户。
2. 用 Firebase CLI 导出
Firebase CLI 的 auth:export 命令会把项目中的所有账号下载到一个文件里。它是为配合 auth:import 把用户迁移到另一个项目而设计的,所以包含密码哈希和盐值。这也让这个文件本身成了凭据:不要把它放进共享网盘,也不要通过邮件发送。哈希和盐值字段需要一个在项目中拥有 Editor 或 Owner 角色的账号。
npm install -g firebase-tools
firebase login
firebase auth:export users.json --project your-project-id- 文件名决定格式:
users.json或users.csv。 - CSV 没有标题行,各列按固定顺序排列:UID、电子邮件、电子邮件已验证、密码哈希、盐值、名称和照片网址,Google、Facebook、Twitter 和 GitHub 各四列,然后是创建时间、上次登录时间、电话号码以及另外几列。Google 的 auth:export 参考文档列出了全部列。时间是以毫秒为单位的 Unix 时间戳。
- JSON 保留 API 自己的字段名:
localId、createdAt、lastSignedInAt、providerUserInfo,以及存放自定义声明的customAttributes(一个 JSON 字符串)。 - 只有用 Firebase 的 scrypt 哈希的密码才会被导出。用其他算法导入、之后再也没有登录过的用户,其哈希和盐值字段为空。
要迁移用户,请用旧项目的哈希参数把文件导入另一个项目,这些参数位于 Authentication > 用户(Users) > ⋮ > 密码哈希参数(Password hash parameters)。用户会保留各自的 UID,并且可以用原来的密码登录。
firebase auth:import users.json --project new-project-id \
--hash-algo=SCRYPT --hash-key=BASE64_SIGNER_KEY --salt-separator=BASE64_SALT_SEPARATOR \
--rounds=ROUNDS --mem-cost=MEM_COST3. 用 Admin SDK 脚本导出
如果要按自己的方式组织列,或者导出需要按计划运行,一段使用 Firebase Admin SDK 的简短 Node.js 脚本就能列出所有用户,并写出带标题行的 CSV。它需要一个能读取用户的账号:项目 Owner 或 Editor,或者 Firebase Authentication Viewer 角色。
- 安装 SDK:
npm install firebase-admin - 登录以获取本地凭据:
gcloud auth application-default login。在服务器上,改为让GOOGLE_APPLICATION_CREDENTIALS指向服务账号密钥。 - 把下面的脚本保存为
export-users.mjs,替换your-project-id,然后运行node export-users.mjs。
// Usage: node export-users.mjs → writes users.csv
import { writeFileSync } from 'node:fs';
import { initializeApp } from 'firebase-admin/app';
import { getAuth } from 'firebase-admin/auth';
initializeApp({ projectId: 'your-project-id' });
const auth = getAuth();
// listUsers returns at most 1,000 users per call, so follow the page token to the end.
const users = [];
let pageToken;
do {
const page = await auth.listUsers(1000, pageToken);
users.push(...page.users);
pageToken = page.pageToken;
} while (pageToken);
// One row per user. Times become ISO 8601. Password hashes are left out: this is a user list, not a backup.
const iso = (time) => (time ? new Date(time).toISOString() : '');
const rows = users.map((user) => ({
uid: user.uid,
email: user.email,
emailVerified: user.emailVerified,
displayName: user.displayName,
phoneNumber: user.phoneNumber,
disabled: user.disabled,
providers: user.providerData.map((provider) => provider.providerId).join(' '),
creationTime: iso(user.metadata.creationTime),
lastSignInTime: iso(user.metadata.lastSignInTime),
customClaims: user.customClaims ? JSON.stringify(user.customClaims) : '',
}));
// Quote any cell with a comma, a quote or a line break.
function cell(value) {
const text = value === undefined || value === null ? '' : String(value);
return /[",\r\n]/.test(text) ? `"${text.replaceAll('"', '""')}"` : text;
}
const columns = ['uid', 'email', 'emailVerified', 'displayName', 'phoneNumber', 'disabled',
'providers', 'creationTime', 'lastSignInTime', 'customClaims'];
const lines = [columns, ...rows.map((row) => columns.map((column) => row[column]))];
// The byte order mark at the start makes Excel read names in any language correctly.
writeFileSync('users.csv', '' + lines.map((line) => line.map(cell).join(',')).join('\r\n'));
console.log(`Wrote ${rows.length} users to users.csv`);- 如果调用因为 API “requires a quota project”(需要配额项目)而失败,请运行
gcloud auth application-default set-quota-project your-project-id后重试。 listUsers按 UID 顺序返回用户,而不是按注册日期。如果需要按注册日期排列,请自行对行排序。- SDK 只会向拥有
firebaseauth.configs.getHashConfig权限的账号返回密码哈希,而且无论如何脚本都不会写入它们。要连同密码一起迁移用户,请使用方法 2。
常见问题
Firebase 控制台能导出 Authentication 用户吗?
不能。用户(Users)标签页上有一个搜索框、添加用户(Add user)按钮、一个刷新按钮,以及一个只有密码哈希参数(Password hash parameters)一项的菜单。要把用户导出为文件,需要使用 Firebase CLI(firebase auth:export)、Admin SDK,或者一个在该标签页上添加“导出”按钮的浏览器扩展程序。
如何从 Firebase 获取所有用户的电子邮件列表?
导出用户,然后保留电子邮件那一列。在 Firexport 的免费导出中,它是 identifier 列,内容与控制台显示的一致:电子邮件,或者对于用手机号登录的用户,是电话号码。在 Admin SDK 脚本中,从 listUsers 收集 user.email。
导出内容包含用户的密码吗?
任何方法都拿不到明文密码,因为 Firebase 从不存储明文密码。firebase auth:export 包含密码哈希和盐值,firebase auth:import 会用它们迁移用户,并让密码继续可用。Firexport 从不读取哈希,Admin SDK 也只有在具备额外权限时才会返回它们。
如何把用户迁移到另一个 Firebase 项目?
在旧项目上运行 firebase auth:export users.json,然后在新项目上运行 firebase auth:import users.json,并带上 --hash-algo=SCRYPT 以及旧项目密码哈希参数(Password hash parameters)中的哈希密钥、盐分隔符、轮数和内存开销。如果文件不含哈希(来自 Firexport 或脚本),每个使用密码登录的用户都得重置密码。
可以在 Excel 或 Google 表格中打开导出的文件吗?
可以。这里的每种方法都会写出 CSV,两者都能打开。Firexport 的 CSV 和脚本写出的 CSV 都以字节顺序标记(BOM)开头,所以 Excel 能正确读取任何语言的名称。如果没有 BOM 的 CSV 中名称显示为乱码,请通过数据 > 从文本/CSV(Data > From Text/CSV)导入,并把文件原始格式(File Origin)设为 65001: Unicode (UTF-8)。
