我有这个脚本,可以更改我们用于测试目的的现有FireBase身份验证用户的所有密码,以将用户重置为“干净”状态。
var admin = require('firebase-admin');
// Input args
var jsonKey = process.argv[2];
var projectId = process.argv[3];
var newPassword = process.argv[4];
var serviceAccount = require(jsonKey);
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://" + projectId + ".firebaseio.com"
});
// FIXME Only for debug purposes
var index = 1;
/**
* https://firebase.google.com/docs/auth/admin/manage-users#update_a_user
*/
function nextUser(uid, timeout) {
setTimeout(() => {
admin.auth().updateUser(uid, {
password : newPassword
})
.then(function() {
console.log(index++ + ') Successfully updated user', uid);
})
.catch(function(error) {
console.log(index++ + ') Error updating user:', error);
});
}, timeout);
}
/**
* https://firebase.google.com/docs/auth/admin/manage-users#list_all_users
* https://stackoverflow.com/a/58028558
*/
function listAllUsers(nextPageToken) {
let timeout = 0;
admin.auth().listUsers(1000, nextPageToken)
.then(function (listUsersResult) {
console.log("Retrieved " + listUsersResult.users.length + " users");
listUsersResult.users.forEach(function (userRecord) {
timeout = timeout + 100
nextUser(userRecord.uid, timeout)
});
if (listUsersResult.pageToken) {
listAllUsers(listUsersResult.pageToken);
}
})
.catch(function (error) {
console.log('Error listing users:', error);
});
}
listAllUsers();
该脚本从本地计算机使用
启动node <filename.js> <path of jsonkey> <projectid> <new password>
您可以看到迭代器正在超时运行,这是在我遇到“我试图用this answer解决的“更新帐户信息的配额超出限额”问题后进行的。
脚本运行正常,所有用户都得到了正确处理(我仅为这种调试添加了顺序计数器),没有抛出“ quota”错误。问题是在脚本末尾,shell提示符没有退出,进程仍然挂起,我需要一个CTRL+C
来杀死它。除了这种行为令人讨厌的部分之外,这还阻止了一个更广泛的脚本,该脚本将调用此脚本,并且不会继续执行下一行命令。
似乎在执行所有setTimeout
函数之后,主进程不会自动关闭。
我该如何解决?
编辑
我尝试了不同的方法:
第二个版本有效,但是速度很慢。因此,我从初始脚本开始,添加了一个“监视器”,等待所有用户完成操作(计数器非常脏),最后关闭脚本
var admin = require('firebase-admin');
// Input args
var jsonKey = process.argv[2];
var projectId = process.argv[3];
var newPassword = process.argv[4];
var serviceAccount = require(jsonKey);
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://" + projectId + ".firebaseio.com"
});
// Index to count all users that have been queued for processing
var queued = 0;
// Index to count all user that have completed the task
var completed = 0;
/**
* https://firebase.google.com/docs/auth/admin/manage-users#update_a_user
*/
function nextUser(uid, timeout) {
setTimeout(() => {
/* ------ Process User Implementation ------ */
admin.auth().updateUser(uid, {
password : newPassword
})
.then(function() {
console.log(++completed + ') Successfully updated user ', uid);
})
.catch(function(error) {
console.log(++completed + ') Error updating user:', error);
});
/* ------ Process User Implementation ------ */
}, timeout);
queued++;
}
/**
* https://firebase.google.com/docs/auth/admin/manage-users#list_all_users
* https://stackoverflow.com/a/58028558
*/
function listAllUsers(nextPageToken) {
let timeout = 0;
admin.auth().listUsers(1000, nextPageToken)
.then(function (listUsersResult) {
console.log("Retrieved " + listUsersResult.users.length + " users");
listUsersResult.users.forEach(function (userRecord) {
timeout = timeout + 100
nextUser(userRecord.uid, timeout)
});
if (listUsersResult.pageToken) {
listAllUsers(listUsersResult.pageToken);
} else {
waitForEnd();
}
})
.catch(function (error) {
console.log('Error listing users:', error);
});
}
function waitForEnd() {
if(completed < queued) {
console.log("> " + completed + "/" + queued + " completed, waiting...");
setTimeout(waitForEnd, 5000);
} else {
console.log("> " + completed + "/" + queued + " completed, exiting...");
admin.app().delete();
}
}
listAllUsers();
有效,快速。对我来说足够了,因为它是测试脚本?
答案 0 :(得分:0)
尝试在setTimeout函数中放置以下退出代码。
process.exit() // exit
我更新了代码。
function listAllUsers(nextPageToken) {
let timeout = 0;
admin.auth().listUsers(1000, nextPageToken)
.then(function (listUsersResult) {
console.log("Retrieved " + listUsersResult.users.length + " users");
listUsersResult.users.forEach(function (userRecord) {
timeout = timeout + 100
nextUser(userRecord.uid, timeout)
});
if (listUsersResult.pageToken) {
listAllUsers(listUsersResult.pageToken);
}
process.exit(0); // exit script with success
})
.catch(function (error) {
console.log('Error listing users:', error);
process.exit(1); // exit script with failure
});
}
此函数将退出Node.js脚本。
process.exit([code]) 用指定的代码结束进程。如果省略,则退出使用“成功”代码0。
要以“失败”代码退出:
process.exit(1);
执行节点的外壳应将退出代码视为1。