您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
This userscript adds a convenient **Export CSV** button to the Firebase Authentication console, allowing you to quickly export all user data to a CSV file for analysis, backup, or migration purposes.
// ==UserScript== // @name Firebase User Data CSV Exporter // @description This userscript adds a convenient **Export CSV** button to the Firebase Authentication console, allowing you to quickly export all user data to a CSV file for analysis, backup, or migration purposes. // @author robomonkey.io // @version 1.0.1 // @license MIT // @match https://*.console.firebase.google.com/* // @icon https://www.gstatic.com/mobilesdk/240501_mobilesdk/firebase_16dp.png // @namespace https://greasyfork.org/users/1502483 // ==/UserScript== (function() { 'use strict'; function createExportButton() { const button = document.createElement('button'); button.textContent = 'Export CSV'; button.className = 'mdc-button mat-mdc-button-base mdc-button--raised mat-mdc-raised-button mat-primary'; button.style.marginLeft = '10px'; button.setAttribute('data-test-id', 'export-csv-button'); return button; } function extractUserData() { const userRows = document.querySelectorAll('table[id="auth-users-table"] tbody tr.mat-mdc-row'); const users = []; userRows.forEach(row => { const identifierElement = row.querySelector('.cdk-column-identifier .identifier-text'); const createdElement = row.querySelector('.cdk-column-created-at .mat-cell-wrapper'); const signedInElement = row.querySelector('.cdk-column-last-login .mat-cell-wrapper'); const identifier = identifierElement ? identifierElement.textContent.trim() : ''; const created = createdElement ? createdElement.textContent.trim() : ''; const signedIn = signedInElement ? signedInElement.textContent.trim() : ''; users.push({ identifier: identifier, created: created, signedIn: signedIn }); }); return users; } function generateCSV(userData) { let csv = 'Identifier,Created,Signed In\n'; userData.forEach(user => { csv += `${user.identifier.replace(/"/g, '""')},${user.created.replace(/"/g, '""')},${user.signedIn.replace(/"/g, '""')}\n`; }); return csv; } function downloadCSV(csvContent) { const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'firebase-users-export.csv'; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); } async function handleExportClick() { const userData = await extractUserData(); if (userData.length === 0) { alert('No user data found to export'); return; } const csvContent = generateCSV(userData); downloadCSV(csvContent); console.log(`Exported ${userData.length} users to CSV`); } function addExportButton() { const addUserButton = document.querySelector('button[data-test-id="add-user-button"]'); if (!addUserButton) { console.error('Add user button not found'); return; } const parentContainer = addUserButton.parentElement; if (document.querySelector('[data-test-id="export-csv-button"]')) { return; } const exportButton = createExportButton(); exportButton.addEventListener('click', handleExportClick); parentContainer.appendChild(exportButton); console.log('Export CSV button added successfully'); } function observePageChanges() { const observer = new MutationObserver(() => { setTimeout(() => { addExportButton(); }, 1000); }); observer.observe(document.body, { childList: true, subtree: true }); console.log('Started observing page changes for export button'); } function init() { addExportButton(); observePageChanges(); console.log('Firebase CSV Exporter initialized'); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();