Technology Blog

Look deep into latest news and innovations happening in the Tech industry with our highly informational blog.

Role-based API with Firebase: Deploy and consuming the API from Angular App

hkis

 
In Our Previous Post about to build the role-based Api with Firebase, we had covered the Role-based Auth, Firebase, Building API and Creating a Firebase HTTP Function. Let’s move on the remaining part of it with this post.

Deploy the API

Great! Now that we have our written the role-based API, we can deploy it to the web and start using it. Deploying with Firebase is super easy, we just need to run firebase deploy. Once the deploy is completed, we can access our API at the published URL.

functions

pic courtesy: toptal.com

api

pic courtesy: toptal.com

Consuming the API

Once our API is deployed, we have several ways to use it—in this tutorial, I’ll cover how to use it via Postman or from an Angular app.

If we enter the List All Users URL (/api/users) on any browser, we’ll get the following:

unauthorized-apiuser

pic courtesy: toptal.com

The reason for this is when sending the request from a browser, we are performing a GET request without auth headers. These means our API is actually working as expected!

Our API is secured via tokens—in order to generate such a token, we need to call Firebase’s Client SDK and log in with a valid user/password credential. When successful, Firebase will send a token back in the response which we can then add to the header of any following request we want to perform.

From an Angular App

In this tutorial, I’ll just go over the important pieces to consume the API from an Angular app. The full repository can be accessed here, and if you need a step-by-step tutorial on how to create an Angular app and configure @angular/fire to use, it you can check this post.

So, back to signing in, we’ll have a SignInComponent with <form> to let the user enter a username and password.

//...
 

<form [formGroup]="form">
   
<div class="form-group">
     <label>Email address</label>
     <input type="email" formControlName="email" class="form-control" placeholder="Enter email">
   </div>

   
<div class="form-group">
     <label>Password</label>
     <input type="password" formControlName="password" class="form-control" placeholder="Password">
   </div>

 </form>


//...

And on the class, we signInWithEmailAndPassword using the AngularFireAuth service.

//... 

 form: FormGroup = new FormGroup({
   email: new FormControl(''),
   password: new FormControl('')
 })

 constructor(
   private afAuth: AngularFireAuth
 ) { }

 async signIn() {
   try {
     const { email, password } = this.form.value
     await this.afAuth.auth.signInWithEmailAndPassword(email, password)
   } catch (err) {
     console.log(err)
   }
 }

 //..

At this point, we can sign in to our Firebase project.

firebase

pic courtesy: toptal.com

firebase

pic courtesy: toptal.com

And when we inspect the network requests in the DevTools, we can see that Firebase returns a token after verifying our user and password.

This token is the one we will use to send on our header’s request to the API we’ve built. One way to add the token to all requests is using an HttpInterceptor.

This file shows how to get the token from AngularFireAuth and add it to the header’s request. We then provide the interceptor file in the AppModule.

http-interceptors/auth-token.interceptor.ts
@Injectable({ providedIn: 'root' })
export class AuthTokenHttpInterceptor implements HttpInterceptor {
   constructor(
       private auth: AngularFireAuth
   ) {
   }
   intercept(req: HttpRequest&lt;any&gt;, next: HttpHandler): Observable&lt;HttpEvent&lt;any&gt;&gt; {
       return this.auth.idToken.pipe(
           take(1),
           switchMap(idToken =&gt; {
               let clone = req.clone()
               if (idToken) {
                   clone = clone.clone({ headers: req.headers.set('Authorization', 'Bearer ' + idToken) });
               }
               return next.handle(clone)
           })
       )
   }
}
export const AuthTokenHttpInterceptorProvider = {
   provide: HTTP_INTERCEPTORS,
   useClass: AuthTokenHttpInterceptor,
   multi: true
}
app.module.ts
@NgModule({
 //..
 providers: [
   AuthTokenHttpInterceptorProvider
 ]
 //...
})
export class AppModule { }

Once the interceptor is set, we can make requests to our API from httpClient. For example, here’s a UsersService where we call the list all users, get the user by its ID, and create a user.

//…

export type CreateUserRequest = { displayName: string, password: string, email: string, role: string }

@Injectable({
 providedIn: 'root'
})
export class UserService {

 private baseUrl = '{your-functions-url}/api/users'

 constructor(
   private http: HttpClient
 ) { }
  get users$(): Observable&lt;User[]&gt; {
   return this.http.get&lt;{ users: User[] }&gt;(`${this.baseUrl}`).pipe(
     map(result =&gt; {
       return result.users
     })
   )
 }

 user$(id: string): Observable&lt;User&gt; {
   return this.http.get&lt;{ user: User }&gt;(`${this.baseUrl}/${id}`).pipe(
     map(result =&gt; {
       return result.user
     })
   )
 }

 create(user: CreateUserRequest) {
   return this.http.post(`${this.baseUrl}`, user)
 }
}

Now, we can call the API to get the user by its ID and list all users from a component like this:

 
//...
   
<ul *ngIf="user$ | async; let user" class="list-group">
     
<li class="list-group-item d-flex justify-content-between align-items-center">

<div>
         
<h5 class="mb-1">{{user.displayName}}</h5>

         <small>{{user.email}}</small>
       </div>

       <span class="badge badge-primary badge-pill">{{user.role?.toUpperCase()}}</span>
     </li>

   </ul>


  
<ul *ngIf="users$ | async; let users" class="list-group">
     
<li *ngFor="let user of users" class="list-group-item d-flex justify-content-between align-items-center">

<div>
         
<h5 class="mb-1">{{user.displayName}}</h5>

         <small class="d-block">{{user.email}}</small>
         <small class="d-block">{{user.uid}}</small>
       </div>

       <span class="badge badge-primary badge-pill">{{user.role?.toUpperCase()}}</span>
     </li>

   </ul>

//...
//...
 users$: Observable&lt;User[]&gt;
 user$: Observable&lt;User&gt;
 constructor(
   private userService: UserService,
   private userForm: UserFormService,
   private modal: NgbModal,
   private afAuth: AngularFireAuth
 ) { }
 ngOnInit() {
   this.users$ = this.userService.users$

   this.user$ = this.afAuth.user.pipe(
     filter(user =&gt; !!user),
     switchMap(user =&gt; this.userService.user$(user.uid))
   )
 }
//...

And here’s the result.
userrole-api

pic courtesy: toptal.com

Notice that if we sign in with a user with role=user, only the Me section will be rendered.

edit-profile

pic courtesy: toptal.com

And we’ll get a 403 on the network inspector.

edit-profile

pic courtesy: toptal.com

From Postman

Postman is a tool to build and make requests to APIs. This way, we can simulate that we are calling our API from any client app or a different service.

What we’ll demo is how to send a request to list all users.

get-api

pic courtesy: toptal.com

Next, on the tab authorization, we choose Bearer Token and we set the value we extracted from Dev Tools previously.

postman

pic courtesy: toptal.com

postman-code

pic courtesy: toptal.com

Hire Angular Developer from us, as we give you high quality product by utilizing all the latest tools and advanced technology. E-mail us any clock at – hello@hkinfosoft.com or Skype us: “hkinfosoft“.

To develop the custom web app using Angular, please visit our technology page.

Content Source:

  1. toptal.com