Search code examples
typescriptrxjsfirebase-authenticationreactive-programmingngrx

Set a state with user data getting getIdTokenResult ()


I'm having trouble putting an object in and putting it in the state of my application.

I need to mount an object with the data returned from firebase.user and user.getIdTokenResult(true).

Example:

userLogged = {
  uid: user.uid, 
  displayName: user.displayName
  admin: false,
};

const token = await user.getIdTokenResult (true);
userLogged.admin = token.claims.admin;

The logic is similar to the one above, however I need to do this using only the Rxjs operators so that I can seclude this object in the state of my application.

@Effect

@Effect()
getUser$: Observable<Action> = this.actions$.pipe(
    ofType(auth.AuthActionTypes.GET_USER),
    switchMap(() => this.authService.getUser().pipe(
        map(user => {

            const userLogged = {
                uid: user.uid,
                displayName: user.displayName,
                admin: false,
            }

            // **** i need call user.getIdTokenResult() ******
            // and get claims.admin and assign to userLogged object admin.

            // authState = {
            //    uid: user.uid,
            //    displayName: user.displayName,
            //    admin: true, // true or false
            // }

            return new auth.Authenticated(userLogged);
        }),
        catchError((err => of(new auth.AuthError(err))))
    )

I'm still adapting myself using reactive programming using Rxjs, so I'm having a hard time merging encapsulated Observables data.


Solution

  • You can use .map() to "retain" the values of user object in your authService.getUser() result. It works albeit being dirty.

    @Effect()
    getUser$: Observable<Action> = this.actions$
        .pipe(
            ofType(auth.AuthActionTypes.GET_USER),
            switchMap(() => this.authService.getUser()),
            switchMap(user => user.getIdTokenResult().pipe(map(claims => ({claims, user}))), //map the user to "retain"
                switchMap(({claims, user}) => {
                    const userLogged = {
                        uid: user.uid,
                        displayName: user.displayName,
                        admin: claims.admin,
                    };
                    return new auth.Authenticated(userLogged);
                }),
                catchError(err => of(new auth.AuthError(err)))))
    

    If you want to retrain more values, suggest that you look into Subjects so that it is cleaner (and the correct way of doing it).