skip to Main Content

I’m using FireStore db and Angular 14. I want to add a custom field (a checkbox isAdmin) for every new user registration.

This is my saveUser method:

saveUser(firstName: any, lastName: any, email: any, password: any) {
    return from(
      createUserWithEmailAndPassword(this.auth, email, password)
    ).pipe(
      switchMap(({ user }) => updateProfile(user, { displayName: firstName }))
    ); 

How can I add isAdmin with the rest of the fields ?

2

Answers


  1. [EDIT]: I just realised that this is some firebase stuff; I should learn to read properly. I’ll leave it here because I took the effort but it’s not a method of yours at all, it’s a built-in thing with firebase to create users.

    Without looking up firebase user creation and management, I imagine the answer will be along the lines that you attach properties to users after their creation, so you need to go through creating them before being able to set anything additional like an isAdmin flag.


    Incorrect answer spam follows:

    So, from your comment it sounds as though you just need to extend that method?

    Assuming you have your checkbox as you say, and it’s saved in some fashion in your component, e.g.

    public onIsAdminChecked(checked: boolean): void {
        this.isAdmin = checked;
    }
    

    Then when they hit save, that value just needs to be passed in…

    public onSaveClick(): void {
        this.service.saveUser(this.firstName, this.lastName, this.email, this.password, this.isAdmin);
    }
    

    And update your method(s) appropriately…

    public saveUser(firstName: any, lastName: any, email: any, password: any, isAdmin: boolean): any {
        return from(
          createUserWithEmailAndPassword(this.auth, email, password, isAdmin)
        ).pipe(
          switchMap(({ user }) => updateProfile(user, { displayName: firstName }))
        ); 
    

    I can’t say what createUserWithEmailAndPassword does, but that needs updating to do whatever it does when creating the user:

    // whatever this does...
    private createUserWithEmailAndPassword(
        auth: any, 
        email: string, 
        password: string, 
        isAdmin: boolean): SomeUserObject {
    
        return {
            email,
            password,
            isAdmin
        };
    }
    

    As a side note: I’d suggest refactoring to reduce the number of params down to just the one; create some UserCreationModel or something, e.g.

    export interface UserCreationModel {
        firstName: string;
        lastName: string;
        email: string;
        password: string;
        isAdmin: boolean;
    }
    

    Then all those methods look much cleaner:

    // property spam only done the once
    const model = {
        firstName: this.firstName,
        lastName: this.lastName,
        email: this.email,
        password: this.password,
        isAdmin: this.isAdmin
    };
    this.service.saveUser(model);
    
    public saveUser(details: UserCreationModel): any {
        ...
        createUserWithEmailAndPassword(this.auth, details)
        ...
    }
    
    private createUserWithEmailAndPassword(this.auth: any, details: UserCreationModel): any {
        return {
            email: details.email,
            password: details.password,
            isAdmin: details.isAdmin
        };
    }
    
    Login or Signup to reply.
  2. I’d recommend not having an ‘isAdmin’ property on the user’s profile in Firebase’s Firestore. Use a Firebase cloud function to create what’s called, a user claim. Here is an example of my cloud function. I restrict only an admin to create other admins, of course, remove this part the first time you run it.

    exports.addAdminRole = functions.region('australia-southeast1').https.onCall((data, context) => {
      if (context.auth?.token.Admin !== true) {
        return { error: 'Only an admin can add other admins.' }
      }
      return admin.auth().getUserByEmail(data.email).then(user => {
        return admin.auth().setCustomUserClaims(user.uid, {
          admin: true
        });
      }).then(() => {
        return {
          massage: `Success, ${data.email} has been made an admin.`
        }
      }).catch(err => {
        return err;
      });
    });
    

    This will make your security rules work easier as well.

    See here – https://firebase.google.com/docs/auth/admin/custom-claims

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search