I am learning about Firebase and after reading the documentation, there are still some aspects that I find confusing. I am working on creating an administrative panel on the client-side to handle CRUD operations for users. The application will not have a sign-up page; instead, the admin will be responsible for creating and activating users.
My understanding is that Firebase does not store user data in the "Firestore" app's collection. Even if I create a user collection, it will not automatically include fields like {email, displayName, password, phone, emailVerified, disabled}. This data is stored somewhere else and can only be accessed through Firebase-admin functions.
If this is the case, would it be best practice to create an HTTP function for admins to create users, assign roles, and manually manage unique fields like {email, displayName, phone}? If more properties need to be added to a user, should a profile collection be created and associated with the user after creation? All rules and validation need to be handled in the function. How can errors triggered by admin.auth().createUser(newUser) be effectively managed? Is there a project or boilerplate that demonstrates best practices for Firebase?
exports.createUser = functions.https.onCall(async (data, context) => {
if (!context.auth) {
createError('unauthenticated');
}
const roles = data.roles;
if (!roleIsValid(roles) || !userValid(data)) {
createError('dataInvalid');
}
const id= context.auth.uid;
const caller = await admin.auth().getUser(id);
if (!caller.customClaims.admin) {
createError('notAdmin');
}
const newUser = {
displayName: data.displayName,
password: data.password,
email: data.email,
emailVerified: true,
disabled: false
}
//todo: how to check all users if email, displayName, phone exists before creating user
const user = await admin.auth().createUser(newUser);
const userId = user.uid;
const claims = {};
roles.foreach(role => claims[role] = true);
await admin.auth().setCustomUserClaims(userId, claims);
await admin.firestore().collection("profile").doc(userId).set(data.profile);
return {message: 'User successfully created.'};
});