Firebase is a platform for running and managing apps on the cloud. It’s a fully-featured “backend as a service” (BaaS) that scales automatically to millions of users. It offers tons of features for development (authentication, database, storage, messaging), user engagement (insights, experimentation, customization), and operations (testing, troubleshooting of stability and performance, feature rollout, and adoption monitoring). You just focus on writing your awesome app and let Firebase manage the infrastructure and much of the tedious operational concerns.
Firebase is part of Google Cloud.
Make sure to get familiar with:
As of October, 2021, Firebase provides these 18 products:
Currently the Firebase documentation groups the products into three main areas:
There are additional sections in the documentation not tied to any of the main products, but are good to know about:
The documentation also shows how to link other Google products into your Firebase app, such as Google AdMob and Google Ads.
There are three main ways to use Firebase:
The general idea with Firebase is to create a project then enable just the services you need.
When using Firebase from JavaScript, you could in theory (but don’t really do this) make a Vanilla JavaScript app and bring in additional products with script tags in your HTML, for example:
<body> <!-- Your HTML here --> <!-- Firebase stuff at the end --> <script type="module"> // Always import this one import { initializeApp } from 'https://www.gstatic.com/firebasejs/9.2.0/firebase-app.js' // Import just the services you need, for example, here are three of them import { analytics } from 'https://www.gstatic.com/firebasejs/9.2.0/firebase-analytics.js' import { auth } from 'https://www.gstatic.com/firebasejs/9.2.0/firebase-auth.js' import { firestore } from 'https://www.gstatic.com/firebasejs/9.2.0/firebase-firestore.js' const app = initializeApp({ /* Your config */ }); // Now use the app object to initialize the other services... </script> </body>
Instead, you really should build an app with Node. Take advantage of systems that build Node-based apps with module bundlers. Things like create-react-app set everything up for you. If you used something like this, then you will:
npm install firebase
and include in your code somewhere something like:
import { initializeApp } from 'firebase/app'; import { getFirestore, /* and maybe other things */ } from 'firebase/firestore'; import { getAuth, /* and maybe other things */ } from 'firebase/auth'; // ... and do the same for other services you need const app = initializeApp({ /* Your config */ }); const db = getFirestore(app); const auth = getFirestore(app); // ... and do the same for other services you need
Check the documentation for Firebase setup on iOS+ (Swift and Objective C), Android (Java and Kotlin), Unity, or Flutter.
If you are using Firebase form a server, check the docs for how to get set up with the Admin SDK.
Firebase is part of the Google Cloud, so if you are connecting to Firebase services from a server, or the console, your authentication and authorization will be configured through Google Cloud’s IAM.
But what about that SDK for the web client?, How can a web client talk to...a database 😬? The answer is: security rules. You configure rules that will examine all requests from a client—the same kinds of rules you would put in a server that your write yourself. (These security rules apply only to client SDKs; server, console, and API access use IAM instead).
It’s a good idea to learn everything you can about security rules, both in terms on the general approach and the specifics for different products:
So, yup, if a web client is talking directly for Firebase, there is no way to hide your database credentials at all, and you must rely on the security rules to prevent all the bad things. You can “do a little more” beyond the security rules, for example, you can:
You might also find some articles such as How to Keep Your Firebase Project Safe and Secure from everyone.
If you have a Google account and are logged in, you can go directly to your Firebase Console and start exploring. Maybe look at the overview page of the docs and follow links to various guides, codelabs and tutorials, quickstarts, and samples. The Fundamentals page is a good one.
After browsing the guides, reading about the fundamentals, doing a quick start or code lab, and maybe watching some introductory videos, you will be ready to create a Firebase project of your own from scratch.
Not quite ready? Let’s do a code-along!
Let's build a blog web application using React with Firebase Authentication and Firestore.
useState
and useEffect
.npm install -g firebase-tools
, then make sure you now have a new terminal command firebase
. (In addition to doing things in the Firebase console on the web, you sometimes need to do things on the command line.)$ npm install $ code . $ npm start
. ├── README.md ├── package.json ├── package-lock.json ├── public │ ├── index.html │ ├── favicon.ico │ ├── logo192.png │ ├── logo512.png │ ├── manifest.json │ └── robots.txt └── src ├── index.js ├── index.css ├── components │ ├── App.js │ ├── App.css │ ├── App.test.js │ ├── Article.js │ ├── ArticleEntry.js │ └── Nav.js ├── services │ └── articleService.js └── setupTests.js
npm install firebase
in your project terminal window, (3) copy the “Add Firebase SDK” code (make sure the npm radio button is checked) into a new file in your project, src/firebaseConfig.js. The next step on the page is to npm install -g firebase-tools
, but you did that already. We’ll wait and do the deploy step later, so go back to the Firebase console now.import { initializeApp } from "firebase/app" import { getAuth } from "firebase/auth" import { getFirestore } from "firebase/firestore" const firebaseConfig = { // THE CONFIG FROM YOUR FIREBASE CONSOLE } export const app = initializeApp(firebaseConfig) export const auth = getAuth(app) export const db = getFirestore(app)
import { useState, useEffect } from "react" import { signInWithPopup, GoogleAuthProvider, signOut } from "firebase/auth" import { auth } from "../firebaseConfig" export function SignIn() { return <button onClick={() => signInWithPopup(auth, new GoogleAuthProvider())}>Sign In</button> } export function SignOut() { return ( <div> Hello, {auth.currentUser.displayName} <button onClick={() => signOut(auth)}>Sign Out</button> </div> ) } export function useAuthentication() { const [user, setUser] = useState(null) useEffect(() => { return auth.onAuthStateChanged((user) => { user ? setUser(user) : setUser(null) }) }, []) return user }
import { useEffect, useState } from "react" import Nav from "./Nav" import Article from "./Article" import ArticleEntry from "./ArticleEntry" import { SignIn, SignOut, useAuthentication } from "../services/authService" import { fetchArticles, createArticle } from "../services/articleService" import "./App.css" export default function App() { const [articles, setArticles] = useState([]) const [article, setArticle] = useState(null) const [writing, setWriting] = useState(false) const user = useAuthentication() // This is a trivial app, so just fetch all the articles only when // a user logs in. A real app would do pagination. Note that // "fetchArticles" is what gets the articles from the service and // then "setArticles" writes them into the React state. useEffect(() => { if (user) { fetchArticles().then(setArticles) } }, [user]) // Update the "database" *then* update the internal React state. These // two steps are definitely necessary. function addArticle({ title, body }) { createArticle({ title, body }).then((article) => { setArticle(article) setArticles([article, ...articles]) setWriting(false) }) } return ( <div className="App"> <header> Blog {user && <button onClick={() => setWriting(true)}>New Article</button>} {!user ? <SignIn /> : <SignOut />} </header> {!user ? "" : <Nav articles={articles} setArticle={setArticle} />} {!user ? ( "" ) : writing ? ( <ArticleEntry addArticle={addArticle} /> ) : ( <Article article={article} /> )} </div> ) }
articles
. Each document should have fields title
(of type string), body
(of type string), and date
(of type timestamp). Let Firebase choose the ids.// This service completely hides the data store from the rest of the app. // No other part of the app knows how the data is stored. If anyone wants // to read or write data, they have to go through this service. import { db } from "../firebaseConfig" import { collection, query, getDocs, addDoc, orderBy, limit, Timestamp } from "firebase/firestore" export async function createArticle({ title, body }) { const data = { title, body, date: Timestamp.now() } const docRef = await addDoc(collection(db, "articles"), data) return { id: docRef.id, ...data } } // NOT FINISHED: This only gets the first 20 articles. In a real app, // you implement pagination. export async function fetchArticles() { const snapshot = await getDocs( query(collection(db, "articles"), orderBy("date", "desc"), limit(20)) ) return snapshot.docs.map((doc) => ({ id: doc.id, ...doc.data(), })) }
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /{document=**} { allow write: if request.auth.uid == '****************************'; allow read: if request.auth != null; } } }substituting your Google user id for the asterisk sequence. This way only you can write to the Firestore but anyone can read as long as they are logged in. (You can find your uid on the Auth part of the console if you enabled Google sign-in and you added yourself as the user.)
$ npm run build
firebase
command with npm install -g firebase
, so now we can use it. Do:
$ firebase login
so that you are authenticated for all subsequent commands (it would be sad if Google didn’t check this, right?)
$ firebase init
When asked to select features, just choose hosting, since auth and firestore were already selected in the console. For the other questions: Select your existing project, and choose build when asked about your project’s public directory.
$ firebase deploy
Let’s try out the app in class and look for things to improve. Sure CSS is one thing. But there are likely many other things that should be worked on. Let’s see what we can come up with.
Some initial ideas:
A few things come to mind:
(This list is not exhaustive.)
firebase deploy
(since you have already logged in and initialized the project).