This is a study note of the Firebase Hosting and Cloud Firestore development. It is based on the Firebase Hosting docs and Cloud Firestore docs.

Firebase Hosting

Firebase hosting allows you to serve both static content and dynamic contents supported by Cloud Functions or Clour Run.

Setup

Run firebase init to configure application hosting. The configuration specifies a Firebase project.

All hosting configurations are defined in firebase.json file in the project root. You can specify the public root directory that includes all HTML, CSS and JavaScript files. The default is public\ folder in the project root. Additionally, you can custom error pages, redirects, rewrites, and headers.

The default configuratioin is as the following:

1
2
3
4
5
6
7
8
"hosting": {
  "public": "public",  // the only required attribute for hosting
  "ignore": [
    "firebase.json",
    "**/.*",
    "**/node_modules/**"
  ]
}

Reserved URLs

Firebase Hosting reserves URLs in your site beginning with /__. These reserved URLs are available both when you deploy to Firebase (firebase deploy) or when you run your app on a local server (firebase serve).

The reserved URL has a format /__/firebase/js-sdk-version/firebase-sdk-name.js. For better performance, only load libraries used in applicaiton.

The reserved namespace also provides the configuration neccessary to intialize the hosted application. The configuration and SDK initialization should be loaded after SDKs.

As a result, a sample list of scripts that uses authentication and firestore is as the following:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<!-- Insert these scripts at the bottom of the HTML, but before you use any Firebase services -->
<!-- Firebase App (the core Firebase SDK) is always required and must be listed first -->
<script src="/__/firebase/7.3.0/firebase-app.js"></script>

<!-- Add Firebase products that you want to use -->
<script src="/__/firebase/7.3.0/firebase-auth.js"></script>
<script src="/__/firebase/7.3.0/firebase-firestore.js"></script>

<!-- Load the Firebase SDKs before loading this file -->
<script src="/__/firebase/init.js"></script>

<!-- load application js files after Firebase initializaiton-->

Cloud Firestore

Firestore is a cloud document-oriented database that can sync across client apps through realtime listeners and offers offline support. It provides a rich hierachical data model and expressive querying.

Get Started

The first step is to create a Firebase database. For testing puporse, choose Test mode and select a local close to the users of your application.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// get Firestore
const db = firebase.firestore()

// add data
db.collection('users')
  .add({
    first: 'Ada',
    last: 'Lovelace',
    born: 1815,
  })
  .then(function(docRef) {
    console.log('Document written with ID: ', docRef.id)
  })
  .catch(function(error) {
    console.error('Error adding document: ', error)
  })

// read data
db.collection('users')
  .get()
  .then(querySnapshot => {
    querySnapshot.forEach(doc => {
      console.log(`${doc.id} => ${doc.data()}`)
    })
  })

Data Model

Firebase is a document-oriented database. Data is stored in documents. Each document contains a set of key-value pairs – just like a JavaScrit object or a JSON record.

All documents must be stored in collections. A document can contain subcollections and nested documents, ooops, so good! However, a collection cannot contain subcollection or raw data.

The identifiers of documents within a collection are unique. You can provide an identifier or Firestore can create a random name automatically. Simply assign data to a document within a collection. If either the collection or document doesn’t exist, Firestore creates it.

To access a doc, there are two ways:

  • db.collection('collection-name').doc('doc-id')
  • db.doc('collection-name/doc-id')

Access Data

There are common ways to add data.

  • The set method: db.doc('collection-name/doc-id').set(obj)
  • The add method: db.collection('collection-name').add(obj). Firebase create the doc identifier automatically.

To update data, use docRef.update(obj) method.

Use docRef.delete() to delete a doc.

Use docRef.get() to retrieve a doc. Check doc.exists before use the doc.data.

To query documents with a condition, use where() method, the result is a iterable querySnapshot. Without where(), all documents are returned. The query supports many composable operations.

To listen for realtime updates, use docRef.onSnapshot method. You can listen to multiple documents.

The API doc has detail information.