This article is a simple guide on how to implement google api in angular and how to integrate a user session with a firebase service.

Step 1: Create Angular project

Install Angular CLI.

npm install -g @angular/cli Create new angular project.

ng new firebase-auth-via-google-api-example Go to project directory.

cd firebase-auth-via-google-api-example Install the required dependencies.

npm install --save firebase @angular/fire

npm install --save-dev @types/gapi @types/gapi.auth2 @types/gapi.client

Step 2: Create Firebase project

Go to https://console.firebase.google.com/ Create new project.

Enable Google sign-in in Authentication.

Add a web app

Copy firebase config to src/environments/environment.ts .

export const environment = { ... firebase : { apiKey : "AIzaSyCq9YuvCvVkjdQrhm3hFTQboI2CV_SZnqI" , authDomain : "api-example-e267d.firebaseapp.com" , databaseURL : "https://api-example-e267d.firebaseio.com" , projectId : "api-example-e267d" , storageBucket : "api-example-e267d.appspot.com" , messagingSenderId : "687667050591" , appId : "1:687667050591:web:695d797c2e266a7c" } } ;

Step 3: Setup Google API project

Go to https://console.developers.google.com

Navigate to project Credentials.

Open OAuth 2.0 client IDs - Web client (auto created by Google Service)

Add http://localhost:4200/ to Restrictions - Authorized Javascript origins

Set email in OAuth consent screen.



Copy client ID to src/environments/environment.ts

export const environment = { ... firebase : { apiKey : "AIzaSyCq9YuvCvVkjdQrhm3hFTQboI2CV_SZnqI" , authDomain : "api-example-e267d.firebaseapp.com" , databaseURL : "https://api-example-e267d.firebaseio.com" , projectId : "api-example-e267d" , storageBucket : "api-example-e267d.appspot.com" , messagingSenderId : "687667050591" , appId : "1:687667050591:web:695d797c2e266a7c" , clientId : "687667050591-56og5jl7jah8ijg9ukft5ihbumacqash.apps.googleusercontent.com" } } ;

Step 4: Create the necessary services and components in angular project

Go to angular project.

Create Google API service.

ng generate service GAPI

Copy to src/app/gapi.service.ts import { Injectable } from '@angular/core' ; import { Observable , Observer } from 'rxjs' ; import { environment } from 'src/environments/environment' ; @ Injectable ( { providedIn : 'root' } ) export class GAPIService { private readonly url : string = 'https://apis.google.com/js/api.js' ; private loaded = false ; private loadGapi ( ) : Observable < void > { return new Observable ( ( observer : Observer < void > ) => { if ( this . loaded ) { observer . next ( ) ; observer . complete ( ) ; return ; } const node = document . createElement ( 'script' ) ; node . src = this . url ; node . type = 'text/javascript' ; document . getElementsByTagName ( 'head' ) [ 0 ] . appendChild ( node ) ; node . onload = ( ) => { this . loaded = true ; observer . next ( ) ; observer . complete ( ) ; } ; node . onerror = ( error ) => { observer . error ( error ) ; } ; } ) ; } public async initClient ( baseScopes : string [ ] = [ 'email' ] ) { await this . loadGapi ( ) . toPromise ( ) ; return new Promise < void > ( async ( resolve , reject ) => { try { const initClient = async ( error ) => { if ( error ) { return reject ( error ) ; } try { await gapi . client . init ( { apiKey : environment . firebase . apiKey , clientId : environment . firebase . clientId , scope : baseScopes . join ( ' ' ) } ) ; return resolve ( ) ; } catch ( error ) { return reject ( error ) ; } } gapi . load ( 'client:auth2' , initClient ) ; } catch ( error ) { return reject ( error ) ; } } ) ; } }

Create Google Authentication service.

ng generate service google-auth

Copy to src/app/google-auth.service.ts import { Injectable , NgZone } from '@angular/core' ; import { AngularFireAuth } from '@angular/fire/auth' ; import { environment } from 'src/environments/environment' ; import { auth } from 'firebase/app' ; import { Observable , ReplaySubject } from 'rxjs' ; import { GAPIService } from './gapi.service' ; import * as firebase from 'firebase' ; @ Injectable ( { providedIn : 'root' } ) export class GoogleAuthService { private isLoggedIn$ = new ReplaySubject < boolean > ( 1 ) ; private user$ = new ReplaySubject < firebase . User > ( 1 ) constructor ( public afAuth : AngularFireAuth , public gapiService : GAPIService , private ngZone : NgZone ) { this . isLoggedIn$ . next ( false ) ; this . afAuth . auth . onAuthStateChanged ( async ( user ) => { this . ngZone . run ( ( ) => { this . isLoggedIn$ . next ( Boolean ( user ) ) ; this . user$ . next ( user ) ; } ) } ) ; } get isLoggedIn ( ) : Observable < boolean > { return this . isLoggedIn$ . asObservable ( ) ; } get user ( ) : Observable < firebase . User > { return this . user$ . asObservable ( ) ; } async signOut ( ) : Promise < void > { return auth ( ) . signOut ( ) ; } private async initAuth2 ( baseScopes : string [ ] ) : Promise < void > { await this . gapiService . initClient ( baseScopes ) ; if ( ! gapi . auth2 . getAuthInstance ( ) ) { gapi . auth2 . init ( { client_id : environment . firebase . clientId , scope : baseScopes . join ( ' ' ) } ) ; } } async signIn ( baseScopes : string [ ] = [ 'email' ] ) : Promise < void > { await this . initAuth2 ( baseScopes ) ; const googleUser = await gapi . auth2 . getAuthInstance ( ) . signIn ( { prompt : 'select_account' } ) ; const token = googleUser . getAuthResponse ( ) . id_token ; const credential = auth . GoogleAuthProvider . credential ( token ) ; await auth ( ) . signInAndRetrieveDataWithCredential ( credential ) ; } }

Create login component.

ng generate component google-sign-in

Copy to src/app/google-sign-in/google-sign-in.component.html < ng-container *ngIf = " user$ | async as user; else loggedOut " > < span > {{ user.displayName }} </ span > < img class = " user-photo " src = " {{ user.photoURL }} " > < a (click) = " logout() " > Logout </ a > </ ng-container > < ng-template #loggedOut > < a (click) = " login() " > Login </ a > </ ng-template > Copy to src/app/google-sign-in/google-sign-in.component.ts import { Component , OnInit } from '@angular/core' ; import { GoogleAuthService } from '../google-auth.service' ; import * as firebase from 'firebase' ; import { Observable } from 'rxjs' ; @ Component ( { selector : 'app-google-sign-in' , templateUrl : './google-sign-in.component.html' , styleUrls : [ './google-sign-in.component.scss' ] } ) export class GoogleSignInComponent { user$ : Observable < firebase . User > ; constructor ( private googleAuth : GoogleAuthService ) { this . user$ = this . googleAuth . user ; } login ( ) { this . googleAuth . signIn ( ) ; } logout ( ) { this . googleAuth . signOut ( ) ; } }

Add AngularFireModule and AngularFireAuthModule to src/app/app.module.ts import { BrowserModule } from '@angular/platform-browser' ; import { NgModule } from '@angular/core' ; import { AppRoutingModule } from './app-routing.module' ; import { AppComponent } from './app.component' ; import { GoogleSignInComponent } from './google-sign-in/google-sign-in.component' ; import { AngularFireModule } from '@angular/fire' ; import { environment } from 'src/environments/environment' ; import { AngularFireAuthModule } from '@angular/fire/auth' ; @ NgModule ( { declarations : [ AppComponent , GoogleSignInComponent ] , imports : [ BrowserModule , AppRoutingModule , AngularFireModule . initializeApp ( environment . firebase ) , AngularFireAuthModule ] , providers : [ ] , bootstrap : [ AppComponent ] } ) export class AppModule { } Add <app-google-sign-in> to src/app/app.component.html < div style =" text-align : center " > < app-google-sign-in > </ app-google-sign-in > </ div >

Step 5: Test application authorization

Start application.

npm run start

Go to http://localhost:4200/ and login via google account.

That’s all, now you can extend the capabilities of the application with all the possibilities of google apis and firebase.

The repository of the entire example described in this article is on github.

https://github.com/studioLaCosaNostra/firebase-auth-via-google-api-example

If you have any problems in any of the steps of this guide, please write in a comment about it.

I will try to write back and refine the article. :)