Handling Objects from Firebase within Ionic Framework

Tools used:
Backend: Firebase -- Version: 7.7.0
Frontend: @ionic/angular -- Version: 4.7.1

If you’re not sure how to create an Ionic app and connect it to Firebase then first go through this post.

The Firestore database is formed by Collections and Documents.

A document holds the properties, like for example, a document for a use would have a name, email, picture, etc.

A collection is a list of documents.

Today you’ll learn how to interact with documents on your database.

CRUD

There are 4 main tasks you’ll need to do in most of your apps, they’re known as CRUD (Create, Read, Update, Delete).

Let’s imagine for a moment we’re building a contact list app, see how this 4 apply, you need to:

  • Add new contacts.
  • Edit existing contacts.
  • Show a contact on a page.
  • Remove a contact you no longer want.

Create

Let’s go ahead and add our addContact function, the goal is to add a new contact to our contact list, that contact will have 2 properties, their name, and their email.

import * as firebase from 'firebase/app';
import 'firebase/firestore';

addContact(name: string, email: string) {
  return firebase.firestore().collection('contacts').doc(email).set({name, email});
}

We’re using .set() to create that document with the data we’re passing. When we use set we have to specify an ID for the document, in this case, we’re using their email address as their ID.

If you don’t want to use the email as the ID, you can let Firestore autogenerate one for you, the function would look a bit different:

import * as firebase from 'firebase/app';
import 'firebase/firestore';

addContact(name: string, email: string) {
  return firebase.firestore().collection('contacts').add({name, email});
}

Instead of .set() we’re using .add(), this goes to the contact list and adds the new contact, automatically generating a unique ID.

Read

When it comes to reading file, we have 2 options, we can either read the collection, or we can read the document.

When do you use one or the other? It depends on your app, for example, in the contact list, you’d read the list in the contact list page, and then read a specific document in the detail page of a contact.

Let’s do both, reading the list:

getContactList() {
  return firebase.firestore().collection('contacts').get();
}
getContact(contactId: string) {
  return firebase.firestore().collection('contacts').doc(contactId).get()
}

One thing to keep in mind, .get() returns a promise, so you’ll need to use it with either async/await syntax or a .then/() to access the actual response from Firestore. For example:

contactList: any[];
constructor() {
  this.getContactList().then( contacts => this.contactList = contacts);
}

Update

In the context of the contact list app, we need an update function to change either the email or name of our contact (or both?).

There are 2 ways we can do this, the first one is to use the regular update function, this will update whatever properties you pass, and leave the rest untouched.

updateContact(contact) {
  return firebase.firestore().collection('contacts').doc(contact.id).update(contact);
}

So, if for example you change the user’s name, the email will still be the same.

There’s one catch though, if there’s no document there, because it was deleted, it was never created, etc. You’ll get an error.

That’s were we can use .set() again, it will make sure to write to that document, if there’s no document there, it will create it.

It is destructive, so if you pass only one property, it will update that property and remove everything else.

Unless you pass a property called merge, for example:

updateContact(contact) {
  return firebase.firestore().collection('contacts').doc(contact.id).set(contact, {merge: true});
}

This way it will behave more like an update, and if the document isn’t there, it will create a new one with the data you’re passing it.

Delete

Now we need to remove a user from the database, for this we we’ll create a reference for the document we want to delete, and then call the .delete() method on it.

removeContact(contactId): Promise<any> {
  return firebase.firestore().collection('contacts').doc(contactId).delete();
}

BONUS Query

As an added bonus, let’s see what happens when I want to filter my users, for example, let’s imagine that we have a 3rd property on our contact list, email, name, and isFamily.

The isFamily property is a boolean that’s set to true for family members.

We want to show the contact list only the family members, for that we’d create a query like this:

getFamilyMembers() {
  return firebase.firestore().collection('contacts').where("isFamily", "==", true).get();
}

We’re using the function .where(), it takes 3 arguments, the name of the property you’re validating against, the operator (equals, greater than, etc.), and the value you’re using to evaluate it.

In our case we’re telling Firestore, bring back the contacts where the isFamily property is set to true.

Got any questions, leave a comment below or shoot me an email 😃