Firebase has been around for a while now. The underdog serverless cloud-based database can be rather fun to use once you get your head around it.
However, the hard part is finding resources that isn’t overwhelming for newbies to read and follow along. I’m not going to lie — there’s a lot of resources but a lot of it is geared toward intermediate users.
I’ve decided to write this piece with the newbie knowledge level in mind — the sort of guide I wished I had when I first started.
Without further ado, here’s a quick and concise guide on how to create and read things in Firebase.
Before you begin — how to set up Firebase with Angular
To work with Firebase in Angular, you’re going to need to install and import the AngularFireModule
Angular Fire is the official Angular library for Firebase from Firebase Open Source Projects. The library lets you create realtime bindings with your data, implement authentication, register/listen for push notifications.
Angular Fire also supports static HTML, making it perfect for JAMstack implementations.
To install Angular Fire, use the following command in your terminal with an existing Angular project.
npm i --save firebase @angular/fire
To connect your Angular app up with your Firebase database, locate your Firebase config file. You can do this via your project’s console.
Navigate over to Project settings and scroll down. If you haven’t already done so, you’ll need to register a new app against the database via the Add app button. Once that’s done, you should have something similar to the screenshot below.
You’re going to need the firebaseConfig
object provided by Firebase.
Copy and paste your firebaseConfig
details over to your environment.ts
file. This can be found in the environments
folder of your project.
You should end up with firebaseConfig
inside your environment
object.
export const environment = {
production: false,
firebaseConfig: {
apiKey: "xxx",
authDomain: "xxxx.firebaseapp.com",
databaseURL: "https://xxxx.firebaseio.com",
projectId: "xxxx",
storageBucket: "xxxx.appspot.com",
messagingSenderId: "xxxxx"
}
};
Head to your app.
module
.ts
file and import the following things:
import { environment } from "src/environments/environment";
import { AngularFireModule } from "@angular/fire";
Initialize your firebaseConfig
with AngularFireModule
@NgModule({
...
imports: [
...
AngularFireModule.initializeApp(environment.firebaseConfig)
]
...
})
And that’s basically it to set up the barebones of Angular and Firebase together.
Notes on Cloud Firestore
There are two types of databases available and provided by Google’s Firebase services — the first is the original Realtime Database and the second being Cloud Firestore.
If you’re using Realtime Database, you’ll need to import AngularFireDatabase
into your app.module.ts
file. Queries made to the Realtime Database is similar to Firestore.
The code snippets in this tutorial are limited to Firestore only for length purposes, and to prevent any confusion between the two.
If you’re using Cloud Firestore, you’ll need to import AngularFirestore
into your app.module.ts
file. The rest of the code available in this tutorial is also applicable and relevant toward getting things to work.
How data structuring works in Firebase
Firebase is a noSQL database. The way it works is that there are no tables and rows as such. Rather, data is arranged as collections and documents.
A collection is a group of documents.
A document is like a row of data. Each document has a set of key-value pairs. Unlike traditional SQL, where each row has to be the same, each document’s structure can be whatever it wants to be. Data integrity is based on the developer rather than pre-defined constraints set in the data architecture.
Creating records with Firebase
In your Angular service, import AngularFirestore
.
import { AngularFirestore } from '@angular/fire/firestore';
Declare it inside your constructor so you can use it in your service’s code.
constructor( private firestore: AngularFirestore ) {}
Create a promise function stating the collection and data you want. On a technicality, you don’t have to use a promise but it’s just easier to work with when you use it in other parts of your code.
exampleCreate(data){
return new Promise<any>((resolve, reject) => {
this.firestore
.collection("collectionNameHere")
.add(data)
.then(
res => {},
err => reject(err)
)
}
)}
The collection name is needed so Firebase knows where to save the document record. You can pass in any kind of data, on condition that it’s a valid object.
Reading records from Firebase
There are multiple ways to read records from Firebase. Here are some commonly used ones.
Please note that you’ll need to still import AngularFirestore
into your service if you haven’t already done so. Instructions on how to do this at the beginning of the create section.
Reading from a collection
A collection in Firebase is a group of documents. In a way, a collection is like a category of documents.
You can read from a collection by querying it directly via the collection name. There are four different types of methods that you can use to keep track of any changes that may occur against your Firebase data.
The base query code looks something like this:
exampleGetCollection(){
return
this.firestore
.collection("collectionNameHere")
// you can either use:
// .valueChanges()
// .snapshotChanges()
// .stateChanges()
// or .auditTrail()
}
About valueChanges()
This will return a list of data. There is no document metadata and makes it simple to render to a view.
Great if you just need to display data on a page. Your data will update when your database is also updated to remain synchronized.
About snapshotChanges()
Returns the current state of your collection that is synchronized against your current databases’ data. There is an additional DocumentChangeAction[]
array that contains additional metadata against DocumentReference
, the document id, and array index of a single document.
To make things easier, you can map the meta and actual data into separate parts.
this.exampleItems = this.firestore
.collection("collectionNameHere")
.snapshotChanges()
.pipe( map(
actions.map( a =>
{
const data = a.payload.doc.data();
const id = a.payload.doc.id;
return {id, ...data}
}
)
));
About stateChanges()
This will return the data as a list + associated meta data. The difference between stateChanges()
and snapshotChanges()
is that stateChanges()
emits the changes as they occur rather than syncing it.
About auditTrail()
Same features and functionalities at stateChanges()
but with a trail of events that’s ocurred in an array. This can help with debugging.
Reading from a document
A document presented as a JSON object with key-value pairs. A specific document is akin to a row in an SQL table.
To read a specific document in your Firestore database, you need to import AngularFirestoreDocument
into the service where you’re going to be using it.
import { AngularFirestore, AngularFirestoreDocument } from '@angular/fire/firestore';
To query a document, you’ll need the collection name and the id to create a document path. Use this document path inside .doc()
So your code should look something like this:
exampleGetDocument(){
return this.firestore
.doc('collectionName/docID')
// you can use either:
// .valueChanges()
// or .snapshotChanges()
}
About valueChanges()
This will return only the data and no metadata.
About snapshotChanges()
This will return an observable as DocumentChangeAction
. The metadata that comes with it contains the DocumentReference
and document id.
And that’s basically it for when it comes to basic reading actions with Firebase and Angular.
Querying is a bit more complex and out of scope for this piece — but more around Firebase will be published soon.
Thank you for reading and I hope you’ve found this piece useful!