Deploying Angular with Firebase: Using Cloud Functions

Deploying Angular with Firebase: Using Cloud Functions

In our last article we see how angular can be deployed with the Firebase hosting service, one that can be used to host static web pages, in the case was used to host an Angular app, displaying our application to everyone to see it. But this application don't receive any new value or access another service, like a database. To resolve this problem we will use a service also provide by firebase, Cloud Function, to fetch a string from firebase cloud function.

Cloud Functions are one of the many services provide in our firebase project, and possesses different types of functions each providing a different service. For more details lets reed what the Firebase docs says about it.

“Cloud Functions for Firebase lets you automatically run backend code in response to events triggered by Firebase features and HTTPS requests. Your code is stored in Google's cloud and runs in a managed environment. There's no need to manage and scale your own servers.”

So Firebase Cloud Functions will let us build a back-end for our Angular Application, specially because it can listen to http requests, and it's this type of functions we are gonna use. But first let just see the others uses for the cloud functions:

  • Cloud Firestore triggers, that can handle Cloud Firestore events;
  • Realtime database triggers, that can handle Real time Database events;
  • Firebase authentication triggers, this function can be trigger by the creation or deletion of an user;
  • Google Analytics for Firebase triggers, function that can be trigger by events that help you to understand how users interact with your application;
  • Crashlytics trigger, functions that can be trigger by events like new issues, regressed issues, and velocity alerts;
  • Cloud storage triggers, a function that responds to events like uploading, updating and deleting of files or folders in the Cloud Storage;
  • Cloud pub/sub triggers, functions that can be trigger by Cloud pub/sub events, this being a globally distributed message bus that automatic scales as you need;
  • And by last but not least, HTTP triggers, a function that can trigger by any of the following http methods GET, POST, PUT, DELETE and OPTIONS.

Now, that we have a grasp of Firebase functions let’s implement our function. Here are our prerequisites and steps in this article:

  • First we need an Angular applications hosted in a Firebase project (the one builded in our last post should serve);
  • Download firebase-tools and login with firebase;
  • Then we create our cloud function using firebase-tools;
  • Create a service in our Angular app, one we can use to call the cloud function;
  • Serving both Angular and cloud function locally;
  • Deploying our angular app modifications and along firebase functions.


1 - Angular Application

First we need a Angular application, one we can use to call the cloud function and to display its message. You can create our own or use the one created in our last article, the important is to host in Firebase Hosting service a webpage that can call our function. In this article we are gonna continue using the application deployed previously.


2 - Downloading Firebase tools.

So, in order to create a function we need to have installed in our system firebase tools, if you already have firebase installed skip this step. To do this open a terminal, doesn't matter where, and enter

npm install -g firebase-tools

As we are using the global flag, -g, npm will install firebase-tool globally. After that we must login with firebase

firebase login

and done!


3 - Create Firebase Cloud Function

Now it’s time to create our function, and you will see that is a very simple processes thanks to firebase-tools. Using firebase tools we just need to call follow by the command “init” and the feature we would like to initiate, like this “firebase init <feature>”, if the <feature> field is neglected firebase setup will ask you to select a feature to proceed. So, just choose a folder to hold the function project, open a terminal in that folder and enter

firebase init functions

Now firebase tools will walk you through a setup, don’t forget to choose the right project, the processes is very intuitive and you shouldn’t have any issues. After that installation is completed our project folder should look like this

project
│   .firebaserc
│   firebase.json
│
└───functions
    │   index.js
    │   package.json
    │
    └───node_modules

Let’s examine what firebase tools has build for us. In the root of the project wee have the .firebaserc, in which the code that defines your target project as the default for this cloud functions, and also helps to change the target project quickly; the firebase.json, that can describe the properties of our project; package.json, the basic json file for describing our code in node projects; the index.js, the main source code for our cloud functions; and the node_modules, the directory where project dependencies are installed.

So, with the cloud functions project setup we just need to create a function. Just for precaution make sure the projects dependencies declared in the package.json are installed, the firebase-tools installation should do it for you in it’s last step, but it does no harm to double check. Now, let’s write a cloud function.

In the index.js file you should find the following code

const functions = require('firebase-functions');



// // Create and Deploy Your First Cloud Functions

// // https://firebase.google.com/docs/functions/write-firebase-functions

//

// exports.helloWorld = functions.https.onRequest((request, response) => {

//  response.send("Hello from Firebase!");

// });

In the first line we see the file importing firebase functions, the rest that’s commented displays a link for a firebase functions tutorial and a default function, and it’s this one we are gonna use in this tutorial, just with a few changes. Let’s uncomment the function, change it a little, and serve it locally.

const functions = require('firebase-functions');



// // Create and Deploy Your First Cloud Functions

// // https://firebase.google.com/docs/functions/write-firebase-functions

//

exports.helloWorld = functions.https.onRequest((request, response) => {

  response.send("Hellooo Angular... from Firebase with love!");

});

With node_modules installed, go to the root folder of the cloud function project and enter

firebase serve

this should appear in the terminal.

if not, check your node_modules to see if exists ; ], case not just run in the terminal npm install in the index folder.

All right our cloud function is being served in http port 5000, more specifically in the address http://localhost:5000/<your-project-id>/<your-choosen-server-central>/<function-name>, in this case the function name is helloWorld, being http://localhost:5000/<your-project-id>/<your-choosen-server-central>/helloWorld

This can be verify in different way, with curl, typing in the terminal curl <address>, or through Postman, Insomnia other method or your choosing.

this should be your response.

So the function works right?!... not quite. If we deploy our function as it is we are gonna receive the following error, “No 'Access-Control-Allow-Origin”, this will happen because our cloud function and our hosted application aren’t in the same domain, to circumvent this problem we have some options, and the one of then is CORS. Burrowing a quote from Thierry Templier, he sad that “Cross Origin Resource Sharing(CORS) allows us to use applications whitin browser wen the domains aren’t the same”. You should read Thierry blog post if you want to learn more about CORS.

Ok, so we are gonna use CORS to allow our Angular app http request be accepted in our cloud function, and the processes is very straight forward.

Open the index.js file in our cloud function and let’s import the cors library.

const cors = require('cors')({

   origin: true

});

With cors imported let’s change our helloWorld http method

exports.helloWorld = functions.https.onRequest((request, response) => {

   cors(request,response, () => {

       response.send("Hellooo Angular... from firebase with love!");

   });   

});

With the function read we can deploy to the firebase services. In terminal type

firebase deploy --only functions

And it’s read… our cloud function are save and available in the firebase cloud functions of your choose project.

Now we need just to create a simple http request in our Angular application to call our function. You guys remember our last angular application, served in the firebase host service, the one that only displays a simple message, this

So, what we're gonna do now? We are gonna create a button that calls our cloud function method and a field to display the functions response. So first let’s create a service to call our cloud function.

In the terminal, go to the app folder in the Angular app. Create a folder called services

mkdir services

after that go inside the new folder and create service that we are gonna call HelloService. If your are using angular CLI, just type ng g service Hello. This id how the service should look.  

@Injectable({

  providedIn: 'root'

})

export class HelloService {



  constructor(private _http: Http) { }



  public onHello(): Observable<any> {

    return this._http.get(<cloud function address>)

      .pipe(map(response => response.text()));

  }

}

Your cloud function address can be verify in the firebase site, but the syntax is something like this “https://<server central>-<project id>.cloudfunctions.net/<function name>”.

Also, don’t forget to add the service in the app.module as providers.

Now with our HelloService ready the only thing left is to callet and to display it’s message. So let’s change the app.component.html to look like this

<div style="text-align:center">

  <h1>

    Hello Firebase!

  </h1>



  <h2>Angular app deployed in the Firebase Host</h2>



  <h3>Call Firebase Function</h3>



  <button (click)="onClick()">Say Hello to Firebase</button>



  <h3 *ngIf="isCalling">Incoming response... </h3>



  <h2 *ngIf="response && !isCalling"> {{response}} </h2>

</div>

And it’s typescript file to this

@Component({

  selector: 'app-root',

  templateUrl: './app.component.html',

  styleUrls: ['./app.component.css']

})

export class AppComponent {

  title = 'app';



  callStatus: 'CALLING' | 'WAITING' = 'WAITING';



  response: string;



  constructor(private _helloService: HelloService) { }



  onClick() {

    this.callStatus = 'CALLING';

    this._helloService.onHello()

    .pipe( finalize( () => this.callStatus = 'WAITING'))

    .subscribe(

      res => {

        console.log('res', res);

        this.response = res;

      },

      err => console.error('Call unsuccessful', err)

    );

  }



  get isCalling() {

    return this.callStatus === 'CALLING';

  }

Now let’s serve it locally to see if works. At the app root folder type in the terminal

ng serve

As we have seen in the last post our app will be served locally in the 4200 port, by entering the address localhost:4200 you will be able to see our app page calling the cloud function already in the fibase service and receive it’s answer, just like the image bellow.

Pressing the button will fire the http request that receives the answer “Hellooo Angular... from Firebase with love!”, so it’s working, now we can deploy our app.

First we need to build our app. Go to the root folder and type

ng build --prod

The app will be build in the dist folder, after that is done just deploy to firebase.

fibase deploy

Now both Angular application and cloud function are hosted in the fibase project. Just go to the project, enter in the Angular hosted address, and call the cloud function… and there is the same response wee receive in local host.

So it’s done, thanks for staying in to the end of this article. You can see the the project with cloud function here. Until next time.

To view or add a comment, sign in

More articles by Carlos Eduardo Ferreira Ramos

Others also viewed

Explore content categories