我对可调用的Firebase云功能( exports.listAllUsers )有问题。
后端:Nodejs和Firebase-Cloud_functions使用 admin.auth()。listUsers
问题:结果(usersList;具有用户uid的数组)在cloud-functions-emulator(日志)中确定,但在客户端中不正确(浏览器中的console.log(usersList)为空)
也许是与...有关的问题:对诺言的理解不佳。第二个代码示例正在使用async / await,但未使用.then()。
函数 listAllUsers 的代码基本上是从文档复制并粘贴的(原始代码片段:https://firebase.google.com/docs/auth/admin/manage-users#list_all_users)。我的代码修改为5(代码中的注释),以获取用户uid的列表:
exports.listAllUsers = functions.https.onCall(() => { // -1) callable function
const usersList = ['12323211'] // ----------------------2) first user uid, just a sample
function listAllUsers (nextPageToken) {
// List batch of users, 1000 at a time.
admin.auth().listUsers(1000, nextPageToken)
.then((listUsersResult) => {
listUsersResult.users.forEach((userRecord) => {
usersList.push(userRecord.uid) // --------------3) get users uids
})
if (listUsersResult.pageToken) {
// List next batch of users.
listAllUsers(listUsersResult.pageToken)
}
console.log(usersList) //-------------------------4) list users uid (cloud functions console)
return usersList //-------------------------------5) return to the client the same as showed at the console
})
.catch((error) => {
console.log('Error listing users:', error)
return null
})
}
// Start listing users from the beginning, 1000 at a time.
listAllUsers()
})
客户端中的方法是...
getUsersList: async function (userType) {
const usersList = await this.$fb.functions().httpsCallable('listAllUsers')()
console.log('usersList: ', usersList)
}
我正在使用Firebase模拟器。云功能日志正常,您可以看到示例uid和其他uid:
cloud function emulator console output
但是我在客户端没有得到相同的信息:
我认为我在做与诺言有关的错误...因为简化了代码,所以在异步/等待中工作
exports.listAllUsers = functions.https.onCall(async () => {
try {
listUsersResult = await admin.auth().listUsers()
return listUsersResult
} catch (error) {
console.log('Error listing users:', error)
return null
}
})
Browser console output (reduced code with async/await)
但是在then()中却不起作用...
exports.listAllUsers = functions.https.onCall(() => {
admin.auth().listUsers()
.then((listUsersResult) => {
return listUsersResult
})
.catch((error) => {
console.log('Error listing users:', error)
return null
})
})
Browser console output (reduced code with .then())
我可以使用async / await重构代码的初始片段,但是我对使用原始代码(.then()风格的解决方案很感兴趣;我始终使用async / await,因为我在js上很新)。有人可以帮助我吗?谢谢!
答案 0 :(得分:1)
这是因为在使用async/await
版本的情况下,您通过执行操作正确返回了listUsersResult
listUsersResult = await admin.auth().listUsers()
return listUsersResult
但是,对于then
版本,您不需要。您应该返回整个promise链,如下所示:
exports.listAllUsers = functions.https.onCall(() => {
return admin.auth().listUsers() // !!! Note the return here !!!
.then((listUsersResult) => {
return listUsersResult
})
.catch((error) => {
console.log('Error listing users:', error)
return null
})
})
答案 1 :(得分:1)
最后,我决定为我的云功能编写一个async/await
版本。第一个代码片段中的then
版本不仅需要在整个Promise链中添加return
(它最初是因为递归性而抱怨,也许是要求我将async
添加到整个Promise链中)。包装函数listAllUsers
...我希望then
版本仅从firebase文档中复制并粘贴,但它需要更多内容。
我想将此自制版本(但经过初步测试)共享为具有异步/等待且无递归的示例,以列出具有admin.auth().listUsers(maxResults?, pageToken?)
的用户:
// get list of users
exports.listAllUsers = functions.https.onCall(async () => {
const usersList = []
try {
let listUsersResult
let nextPageToken
do {
if (listUsersResult) {
nextPageToken = listUsersResult.pageToken
}
// eslint-disable-next-line no-await-in-loop
listUsersResult = await admin.auth().listUsers(1000, nextPageToken)
listUsersResult.users.forEach((userRecord) => {
usersList.push(userRecord.uid)
})
} while (listUsersResult.pageToken)
return usersList
} catch (error) {
console.log('Error listing users:', error)
return null
}
})