我正在注册为第一个用户。
如何仅向 Firebase Firestore 数据库中的第一个用户添加管理员角色?
const auth = firebase.auth();
const db = firebase.firestore();
// sign up the user
auth.createUserWithEmailAndPassword(email, password).then((cred) => {
// set admin to true for the only first user
return db.collection('users').doc(cred.user.uid).set({
admin: true
})
}).then(() => {
console.log();
}).catch(err => {
});
您可以创建一个云函数,当创建用户时会触发该函数。
import * as admin from 'firebase-admin';
import * as functions from 'firebase-functions';
admin.initializeApp({
databaseURL: "https://your-project-name.firebaseio.com"
});
export const onCreateUser = functions.auth.user().onCreate(async (createdUser) => {
const listUsersResult = await admin.auth().listUsers(2);
if (listUsersResult.users.length === 1) {
await admin.auth().setCustomUserClaims(createdUser.uid, {admin: true});
} else {
await admin.auth().setCustomUserClaims(createdUser.uid, {admin: false});
}
return;
});
使用
admin.auth().listUsers(1)
方法,您将获得长度为 1 的用户数组。
如果创建的用户是该项目的第一个用户,该方法将返回一个空数组。如果是这种情况,用户自定义声明将设置为
{admin: true}
。
现在您可以创建一条安全规则,允许该用户访问所有 Firestore 文档。
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if request.auth.uid != null && request.auth.token.admin == true;
}
}
}
可在
request.auth.token
属性上访问自定义声明。
扩展塞巴斯蒂安的答案,这是我通常想到的:
export const initAdminUser = functions.auth.user().onCreate(async (
// we do not need `user` param here as we are not interested in the user in the incoming request
) => {
const listUsersResult = await auth.listUsers(10); // lets make it a safe number
const user = listUsersResult.users.find((u) => u.email !== undefined); // find first user whose email is not undefined
// since this is not a regular User object (it is a UserRecord object), it does not have any `isAnonymous` property. firebase anons do not have any email.
if (user) {
// there are a couple of things you gotta do here
// check if any user exists with admin role
// if does not exist, define this user as admin
// using firestore is highly recommended for easier process, see below
}
});
因此,我将用户角色存储在 Firestore 中,而不是 Firebase Auth 提供的用户声明,因为我的应用程序的范围需要这样做。您也可以使用用户声明。
是的,这个解决方案有点hacky,每个用户创建都会触发这个函数来完成这样一个简单的任务,但这就是我想出的。
另外,请记住,出于某种奇怪的原因(可能是 Google 方面的优化),
UserRecord
返回的 listUsers
的顺序是按 uid
排序的。