/ ionic

Firebase Cloud Functions with Ionic 3

I was super excited when Firebase Cloud Functions were announced, as I'd been looking to integrate server-side functionality into my application(s) without the need for an extra Node solution. As we use them in Learn Ionic 3 From Scratch I figured I'd also make a smaller guide that simply shows turning a message body both into upper and lower case.

Project Setup

Let's start off by generating a new Ionic project.

# New Project 
$ ionic start IonicFirebaseCloudFunctions blank

# Change Directory
$ cd IonicFirebaseCloudFunctions

Now, we can install our Firebase and AngularFire2 dependencies:

# --save is only required for < [email protected]
$ npm install firebase angularfire2 --save

You may also need the Firebase Tools CLI:

$ npm install firebase-tools -g
Setup Firebase

I'd now recommend that you set up Firebase in your project. Navigate to the Firebase Dashboard and create a new project. From here, you'll need to retrieve your API key and set up information so that we can use it in our AngularFireModule.initializeApp().

I'm adding this into a file named firebase.details.ts

export const CONFIG = {
    apiKey: "*",
    authDomain: "*.firebaseapp.com",
    databaseURL: "https://*.firebaseio.com",
    projectId: "*",
    storageBucket: "*.appspot.com",
    messagingSenderId: "*"
};

Let's initialise Firebase inside of our application. Here's a condensed version of our AppModule:

import { AngularFireDatabaseModule } from 'angularfire2/database'
import { AngularFireModule } from 'angularfire2'
import { CONFIG } from "./firebase.details";

@NgModule({
  imports: [
    AngularFireModule.initializeApp(CONFIG),
    AngularFireDatabaseModule
  ]
})
export class AppModule {}

Application

The application we're creating will be a messaging system of sorts. A message contains both a title and body, here's our template:

<ion-header>
  <ion-navbar color="primary">
    <ion-title>
      Messages
    </ion-title>
  </ion-navbar>
</ion-header>

<ion-content padding>
  <ion-item>
    <ion-label floating>Title</ion-label>
    <ion-input [(ngModel)]="title"></ion-input>
  </ion-item>

  <ion-item>
    <ion-label floating>Body</ion-label>
    <ion-textarea rows="7" [(ngModel)]="body"></ion-textarea>
  </ion-item>

  <button block ion-button clear (click)="sendMessage(title, body)">Send Message</button>
</ion-content>

Super simple. Our Component therefore looks like this:

import { Component } from '@angular/core';
import { AngularFireDatabase } from "angularfire2/database";

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
  title: string;
  body: string;

  constructor(private af: AngularFireDatabase) { }
  
  sendMessage(title: string, body: string) {
    this.af.list(`messages`).push({ title, body });
    this.title = "";
    this.body = "";
  }
}

I've added the function parameters just to be super explicit, and after clicking the Send Message button we're setting the content back to an empty string.

At this moment, once we submit a message it's added to Firebase:

Cloud Functions

Functions

Nice. Now we can initialise the Cloud Functions inside of our project with the Firebase CLI:

$ firebase init functions

You'll be asked to select a project and install dependencies. Ensure to select the project created inside your Firebase dashboard.

Firebase Cloud Functions

If we navigate to our functions folder, we should have an index.js file. The file will contain a singular import to firebase-functions, we'll use this to access Firebase specific events and data.

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

In this example I'll be creating an uppercase and lowercase version of the newly created message. Let's start with the lowercase version:

exports.lowercase = functions.database.ref(`messages/{messageId}`)
    .onWrite(event => {
        const messageKey = event.data.key;
        const messageValue = event.data.val();

        const lowerCaseBody = messageValue.body.toLowerCase();
        
        return event.data.ref.child('lowerCase').set(lowerCaseBody);
    });

We have a fairly simple implementation. Essentially, we're awaiting for the database to receive an onWrite event at the messages/{messageId} path.

This gives us access to the written data as an event, therefore allowing us to create variables out of the key and value. I'm then adding a child named lowerCase to the node with the value of the message body toLowerCase().

As you can imagine, creating an uppercase version of our message body is similar:

exports.uppercase = functions.database.ref(`messages/{messageId}`)
    .onWrite(event => {
        const messageKey = event.data.key;
        const messageValue = event.data.val();

        const upperCaseBody = messageValue.body.toUpperCase();

        return event.data.ref.child('upperCase').set(upperCaseBody);
    });

We could do this as part of the same function, but splitting it out into different functions allows us to control side effects.

As you can see, the results of creating a new message automatically converts the body to lowercase and uppercase versions:

Firebase Cloud Functions (2)

Want to put this into practice? Check out the Learn Ionic 3 From Scratch course and the 'HALF' coupon code for a 50% launch discount. We create a real time chat application with Firebase Cloud Functions as well as investigating a variety of key Ionic concepts.

Paul Halliday

Progress Telerik Developer Expert. Course author with students in 110+ countries. BSc (Hons) Computer Science @ UoS. Google accredited Mobile Site professional.

Read More