Firebase云函数deleteUser()生产环境无法删除匿名用户,开发环境运行正常
问题根因
你遇到的问题核心是异步操作未完成就被云函数提前终止,具体原因如下:
forEach不支持异步等待:你在forEach回调里用了async/await,但forEach本身不会等待所有异步回调执行完毕,就会继续执行后续逻辑,你的云函数在所有deleteUser请求执行完成前就已经触发了finished with status: 'ok'的结束信号,Firebase会立即回收函数运行环境,未完成的删除操作直接被中断。- 开发环境和生产环境的差异:开发环境通常函数冷启动慢、资源回收阈值宽松,加上测试环境用户数量少,刚好能在函数回收前跑完所有删除操作,所以看起来运行正常;生产环境资源回收更严格,用户量更大,就会出现删除操作没执行完就被终止的情况。
修复方案
把forEach改成支持异步等待的遍历方式,比如for...of,或者用Promise.all批量处理所有删除任务,参考修复后的代码:
// Delete all Anonymous Users export const cleanupUsers = functions.pubsub.schedule('01 00 * * *') .timeZone('America/Los_Angeles') .onRun(async context => { //Get the list of all Users const allUsers = await admin.auth().listUsers(); // 用for...of等待每个异步操作完成 for (const user of allUsers.users) { console.log('This USER has been read: ', user.email, user.providerData.length); if (user.providerData.length === 0) { console.log('This USER will now be deleted: ', user.email, user.uid); try { const res = await admin.auth().deleteUser(user.uid); console.log('This USER has been deleted: ', res); } catch (err) { console.log('Error on delete of user', err); } } } // 所有操作完成后函数才会结束 return null; });
如果你的生产环境用户量超过1000人,还需要注意listUsers默认最多返回1000条用户数据,需要分页拉取全量用户再处理。
内容的提问来源于stack exchange,提问作者user12121732
相关产品推荐
相关产品推荐

