5

I've been trying to set user custom properties or attributes using auth.updateProfile method but it only save displayName property because it's mentioned in its docs :

this.af.auth.createUser({
   email: formData.value.email,
   password: formData.value.password,
}).then((user) => {
   let userProfile = formData.value;
   userProfile.role = AuthService.ROLE_PATIENT;
   userProfile.displayName = `${formData.value.firstName} ${formData.value.lastName}`;
   user.auth.updateProfile(userProfile).then(function(){
   this.router.navigate(['/']);  
}); 

Now Problem how can i set custom properties of the user so i can get them in FirebaseAuthState

Question: Why i need to save custom properties with each user?

Answer: Because i'm working with Auth Guard to activate a particular route using role property which is saved in the database example:

canActivate(route: ActivatedRouteSnapshot,
              state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
    //Currently I'm using this which only check that user is logged in or not
    return this.auth
      .take(1)
      .map((authState: FirebaseAuthState) => !!authState)
      .do(authenticated => {
        if (!authenticated) this.router.navigate(['/login']);
      });   
  }

But i want one more check to validate the user has the role of patient which i've saved while creating the user above eg: return user.role == 'patient'

Touqeer Shafi
  • 5,084
  • 3
  • 28
  • 45

2 Answers2

1

The existing identity providers in Firebase Authentication have no way to add custom properties. If you want to add custom properties, you will either have to implement a custom identify provider (see minting custom tokens in a trusted process and signing in with a custom token) OR do a client-side look-up of the additional information from an alternate data source (such as the Firebase Database).

Community
  • 1
  • 1
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
0

Perhaps you can do something like this:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
    //Currently I'm using this which only check that user is logged in or not
    return this.auth
      .take(1)
      .map((authState: FirebaseAuthState) => {

        return this.af.database.list('/path/to/account').first().map((account: IAccount) => {

          if (authState && account.role === 'patient') {
            return true;
          }
          else {
            return this.router.navigate(['/login']);
          }
        });
      });
  }

It's quite far-fetched but it might just work. Or help you along the way to find an answer.

Chrillewoodz
  • 27,055
  • 21
  • 92
  • 175