解决办法:
Firebase 是否有任何技巧,例如{ merge: true }
在不删除/覆盖旧变量的情况下设置额外/更多自定义版权主张?
重现步骤:
admin.auth().setCustomUserClaims(uid, { a: 'value' }) // Run this first
admin.auth().setCustomUserClaims(uid, { b: 'value' }) // Then run this after
结果:
{ b: 'value'}
预期成果:
{ a: 'value', b: 'value' }
还是我做错了什么?
setCustomUserClaims
的 Firebase 文档指出:
- 自定义用户声明:对象
开发人员声明设置。如果传递 null,则删除现有的自定义声明。传递大于 1000 字节的自定义声明有效负载将引发错误。自定义声明将添加到用户的 ID 令牌中,该令牌在每个经过身份验证的请求时传输。对于配置文件非访问相关的用户属性,请使用数据库或其他单独的存储系统。
从此说明中并不完全清楚,但语句"如果传递 null,则删除现有的自定义声明"提供了一个提示,即每次调用setCustomUserClaims
时都会完全覆盖自定义声明。
因此,需要按如下方式设置自定义声明:
claims = {
a: 'value',
b: 'value'
}
admin.auth().setCustomUserClaims(uid, claims)
解决办法:addCustomUserClaims
可以创建一个帮助程序函数来合并新声明。
async function addCustomUserClaims(uid, claims) {
const user = await admin.auth().getUser(uid)
let updated_claims = user.customClaims || {}
for (let property in claims) {
if (Object.prototype.hasOwnProperty.call(claims, property)) {
updated_claims[property] = claims[property]
}
}
await admin.auth().setCustomUserClaims(uid, updated_claims)
}
Christopher Peisert的回答是正确的,但它可以做得更干净,因为
admin.auth().getUser(uid).then(({customClaims: oldClaims}) =>
admin.auth().setCustomUserClaims(uid, { ...oldClaims, b: 'value' }))
如果要将此逻辑抽象为函数,可以按
function addCustomUserClaims(uid, claims) {
return admin.auth().getUser(uid).then(({customClaims}) =>
admin.auth().setCustomUserClaims(uid, { ...customClaims, ...claims }))
}
或等效*作为
const addCustomUserClaims = (uid, claims) =>
admin.auth().getUser(uid).then(({customClaims}) =>
admin.auth().setCustomUserClaims(uid, { ...customClaims, ...claims }))