\",\"aspectRatio\":1.7778},\"caption\":\"Full-Stack Firebase on Udemy\"}" %}
10 |
11 | ## Available on Udemy
12 |
13 | 
14 |
15 | We've launched [Full-Stack Firebase on Udemy](https://www.udemy.com/full-stack-firebase/?couponCode=FSFDOTCOM) for the full video experience.
16 |
17 | The Udemy course features 2.5 hours of tightly-edited video walkthroughs. It is the absolute fastest, easiest way to learn Firebase. We've condensed everything on FullStackFirebase.com into video form with free instructor Q&A.
18 |
19 | ## Newsletter
20 |
21 | [Sign up for email updates](http://eepurl.com/ceGkov) 💌
22 |
23 | We'll send you some "getting started" emails. From there on out, we email with a light touch 👍
24 |
25 | ## GitBook vs GitHub
26 |
27 | Read the GitBook or the GitHub repo:
28 |
29 | * [GitBook](https://www.fullstackfirebase.com/): A luxurious reading experience
30 | * [GitHub](https://github.com/how-to-firebase/full-stack-firebase): The delightful and gory details
31 |
32 | ## Beginners Welcome!
33 |
34 | You'll need to know JavaScript. If you're weak on JavaScript... this may not be the course for you.
35 |
36 | Check out the Prerequisites chapter for all of the details.
37 |
38 | You don't need to know anything about Firebase to get started. Just be patient and move slowly through the material.
39 |
40 | If you're already adept with Firebase, then please jump around! The more advanced modules later in the course will be of particular interest.
41 |
42 | We'll cover integration for Angular and React. The Firebase SDK is all vanilla JavaScript, so if you can integrate with Angular and React, you should be able to integrate with any other modern framework.
43 |
44 | ## Modules
45 |
46 | This course consists of a bunch of modules, including:
47 |
48 | * Firebase Console
49 | * Firebase Authentication
50 | * Cloud Firestore
51 | * Realtime Database
52 | * Cloud Functions
53 | * Firebase Storage
54 | * Cloud Messaging
55 | * Firebase Hosting
56 |
57 | ## Module Structure
58 |
59 | Each module will have the following parts:
60 |
61 | * Introduction
62 | * Feature walk-through\(s\)
63 | * Exercise\(s\)
64 | * Downloadable notes
65 |
66 | Some modules will build on each other, so skip around carefully 😉
67 |
68 | ## What to expect
69 |
70 | * Opinionated code
71 | * Angular and React integrations
72 | * You'll need a Firebase account
73 |
74 | We write opinionated code, and we like our courses opinionated as well.
75 |
76 | If you're not familiar with Angular or React, do not worry. The markup and JavaScript is easy enough to read, and we'll stick to vanilla JS as much as possible.
77 |
78 | Firebase's [free Spark plan](https://firebase.google.com/pricing/) is **very generous**. Firebase Functions requires a paid Blaze plan _**IF**_ you want to make external HTTP calls. Otherwise, you can skate by on Spark.
79 |
80 | ## This course is not...
81 |
82 | * 100% framework agnostic
83 | * Exhaustive documentation
84 | * Constantly updated
85 |
86 | Firebase is framework-agnostic... but good luck writing a modern web application without some sort of templating framework.
87 |
88 | We'll reference the [Firebase Docs](https://firebase.google.com/docs/) quite a bit throughout. We will try to duplicate them.
89 |
90 | Firebase changes. A lot. The docs are canonical. Use them. We'll do our best to update this content, but staying 100% current would be a full-time job.
91 |
92 | Have you found an error or a bug? Don't hesitate to [file an issue ](https://github.com/how-to-firebase/full-stack-firebase/issues) or make pull requests 💕
93 |
94 |
--------------------------------------------------------------------------------
/SUMMARY.md:
--------------------------------------------------------------------------------
1 | # Table of contents
2 |
3 | * [Introduction](README.md)
4 |
5 | ## Introduction
6 |
7 | * [Full-Stack Firebase](introduction/full-stack-firebase.md)
8 | * [Why Firebase?](introduction/why-firebase.md)
9 | * [What is serverless?](introduction/what-is-serverless.md)
10 | * [Prerequisites](introduction/prerequisites.md)
11 | * [Overview & Structure](introduction/overview-and-structure.md)
12 | * [Write your first query](introduction/write-your-first-query.md)
13 | * [Links](introduction/links.md)
14 | * [Downloadable Notes](introduction/downloadable-notes.md)
15 |
16 | ## Firebase Console
17 |
18 | * [Introduction](firebase-console/introduction.md)
19 | * [Walkthrough](firebase-console/walkthrough.md)
20 |
21 | ## Firebase Tools
22 |
23 | * [Introduction](firebase-tools/introduction.md)
24 | * [Walkthrough](firebase-tools/walkthrough.md)
25 |
26 | ## Firebase Authentication
27 |
28 | * [Introduction](firebase-authentication/introduction.md)
29 | * [Walkthrough](firebase-authentication/walkthrough.md)
30 | * [Challenge](firebase-authentication/challenge.md)
31 | * [Notes](firebase-authentication/notes.md)
32 |
33 | ## Cloud Firestore
34 |
35 | * [Introduction](cloud-firestore/introduction.md)
36 | * [Walkthrough](cloud-firestore/walkthrough.md)
37 | * [Security Rules](cloud-firestore/security-rules.md)
38 | * [Indexes](cloud-firestore/indexes.md)
39 | * [Challenge](cloud-firestore/challenge.md)
40 | * [Notes](cloud-firestore/notes.md)
41 |
42 | ## Realtime Database
43 |
44 | * [Introduction](realtime-database/introduction.md)
45 | * [Walkthrough](realtime-database/walkthrough.md)
46 | * [Security Rules](realtime-database/security-rules.md)
47 | * [Challenge](realtime-database/challenge.md)
48 | * [Notes](realtime-database/notes.md)
49 |
50 | ## Cloud Functions for Firebase
51 |
52 | * [Introduction](cloud-functions-for-firebase/introduction.md)
53 | * [Walkthrough](cloud-functions-for-firebase/walkthrough.md)
54 | * [Challenge](cloud-functions-for-firebase/challenge.md)
55 | * [Notes](cloud-functions-for-firebase/notes.md)
56 |
57 | ## Firebase Storage
58 |
59 | * [Introduction](firebase-storage/introduction.md)
60 | * [Walkthrough](firebase-storage/walkthrough.md)
61 | * [Security Rules](firebase-storage/security-rules.md)
62 | * [Challenge](firebase-storage/challenge.md)
63 | * [Notes](firebase-storage/notes.md)
64 |
65 | ## Cloud Messaging
66 |
67 | * [Introduction](cloud-messaging/introduction.md)
68 | * [Walkthrough](cloud-messaging/walkthrough.md)
69 | * [Challenge](cloud-messaging/challenge.md)
70 | * [Notes](cloud-messaging/notes.md)
71 |
72 | ## Firebase Hosting
73 |
74 | * [Introduction](firebase-hosting/introduction.md)
75 | * [Walkthrough](firebase-hosting/walkthrough.md)
76 | * [Challenge](firebase-hosting/challenge.md)
77 | * [Notes](firebase-hosting/notes.md)
78 |
79 |
--------------------------------------------------------------------------------
/book.json:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": ["ga"],
3 | "pluginsConfig": {
4 | "ga": {
5 | "token": "UA-6859198-24"
6 | }
7 | }
8 | }
--------------------------------------------------------------------------------
/cloud-firestore/challenge.md:
--------------------------------------------------------------------------------
1 | # Challenge
2 |
3 | ## Cloud Firestore
4 |
5 | ## Find the repo
6 |
7 | We'll be working on a branch of our [firelist-react](https://github.com/how-to-firebase/firelist-react) repo named [challenge-firestore](https://github.com/how-to-firebase/firelist-react/tree/challenge-firestore).
8 |
9 | ## Localhost installation
10 |
11 | Pull [the repo](https://github.com/how-to-firebase/firelist-react) directly from GitHub...
12 |
13 | ```text
14 | git clone https://github.com/how-to-firebase/firelist-react.git
15 | cd firelist-react
16 | git checkout challenge-firestore
17 | ```
18 |
19 | ## Edit environment files
20 |
21 | Update the following files with your own project details:
22 |
23 | * `/.firebaserc`
24 | * `/public/environments/environment.dev.js`
25 | * `/public/environments/environment.js`
26 |
27 | ## Start the app
28 |
29 | Once you're on the branch, make sure to run `yarn` or `npm install` to get your Node.js dependencies.
30 |
31 | Then run `yarn start` or `npm run start` to spin up the development server.
32 |
33 | ```text
34 | yarn
35 | yarn start
36 | ```
37 |
38 | ## Complete the challenge
39 |
40 | Search the codebase for `Challenge Firestore` to find all of the challenges.
41 |
42 | Read the comments and complete the steps in those files.
43 |
44 |
--------------------------------------------------------------------------------
/cloud-firestore/indexes.md:
--------------------------------------------------------------------------------
1 | # Indexes
2 |
3 | Indexes are required in Cloud Firestore whenever you want to use two where-clauses in a single query.
4 |
5 | For example, the following query filters a collection called `uploads` by a `userId` and also orders by a `created` field:
6 |
7 | ```javascript
8 | async function getUploadsByUser(userId) {
9 | const query = window.firebase
10 | .firestore()
11 | .collection('uploads')
12 | .where('userID', '==', userId)
13 | .orderBy('created', 'desc');
14 | const snapshot = await query.get();
15 | return snapshot.docs.map(doc => doc.data());
16 | }
17 | ```
18 |
19 | This query would require indexes on `userId` and `created`.
20 |
21 | ## Console index management
22 |
23 | Queries are super easy to handle via the Console.
24 |
25 | The easiest way to do it is to write whatever queries you like and watch your DevTools console for error messages.
26 |
27 | You'll see an error message in DevTools whenever you attempt to run a query that requires an index. That error message will come with a link that you can click on to take you to your Console.
28 |
29 | Once on the Console, you'll get a prompt to create the required index. Simply confirm and wait for the index to build.
30 |
31 | ## Firebase Tools index management
32 |
33 | The other way to manage indexes is via Firebase Tools.
34 |
35 | When you run `firebase init` in your project folder and opt-in to using Firestore, you'll get a file in your project folder named `firestore.indexes.json`.
36 |
37 | You'll spec out your indexes in `firestore.indexes.json` and run `firebase deploy` or `firebase deploy --only firestore` to deploy your indexes.
38 |
39 | Here's a sample of how your indexes file could look:
40 |
41 | ```javascript
42 | {
43 | "indexes": [
44 | {
45 | "collectionId": "uploads",
46 | "fields": [
47 | { "fieldPath": "userId", "mode": "ASCENDING" },
48 | { "fieldPath": "created", "mode": "DESCENDING" }
49 | ]
50 | }
51 | ]
52 | }
53 | ```
54 |
55 | ## And that's it!
56 |
57 | There's nothing more to Firestore indexes. You just need to be aware of them and adjust them as necessary.
58 |
59 |
--------------------------------------------------------------------------------
/cloud-firestore/notes.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/how-to-firebase/full-stack-firebase/6f96681d45c1c4892423f9a16cbf0d75cbb9826a/cloud-firestore/notes.pdf
--------------------------------------------------------------------------------
/cloud-firestore/walkthrough.md:
--------------------------------------------------------------------------------
1 | # Walkthrough
2 |
3 | ## Open the app
4 |
5 | Open the app at [fogo.howtofirebase.com](https://fogo.howtofirebase.com/).
6 |
7 | ## Open DevTools
8 |
9 | [Sourcemaps are currently broken in Chrome](https://github.com/webpack/webpack/issues/3165) for Fogo as of July 2018.
10 |
11 | This is best done in Firefox.
12 |
13 | Right-click `inspect element` and select the `Debugger` tab. Then click `command + P` to search for and open two files:
14 |
15 | * `observers/images.observer.js`,
16 | * and `queries/images.query.js`.
17 |
18 | 
19 |
20 | 
21 |
22 | ## Video
23 |
24 | {% embed data="{\"url\":\"https://youtu.be/eOXlUYruPjw\",\"type\":\"video\",\"title\":\"Walkthrough: Cloud Firestore\",\"description\":\"Full-Stack Firebase:\\n\\nhttps://www.fullstackfirebase.com/cloud-firestore/walkthrough\",\"icon\":{\"type\":\"icon\",\"url\":\"https://www.youtube.com/yts/img/favicon\_144-vfliLAfaB.png\",\"width\":144,\"height\":144,\"aspectRatio\":1},\"thumbnail\":{\"type\":\"thumbnail\",\"url\":\"https://i.ytimg.com/vi/eOXlUYruPjw/maxresdefault.jpg\",\"width\":1280,\"height\":720,\"aspectRatio\":0.5625},\"embed\":{\"type\":\"player\",\"url\":\"https://www.youtube.com/embed/eOXlUYruPjw?rel=0&showinfo=0\",\"html\":\"\",\"aspectRatio\":1.7778}}" %}
25 |
26 |
--------------------------------------------------------------------------------
/cloud-functions-for-firebase/challenge.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Cloud Functions Challenge
3 | ---
4 |
5 | # Challenge
6 |
7 | ## Cloud Functions
8 |
9 | ## Find the repo
10 |
11 | We'll be working on a branch of our [firelist-react](https://github.com/how-to-firebase/firelist-react) repo named [challenge-functions](https://github.com/how-to-firebase/firelist-react/tree/challenge-functions).
12 |
13 | ## Localhost installation
14 |
15 | Pull [the repo](https://github.com/how-to-firebase/firelist-react) directly from GitHub...
16 |
17 | ```text
18 | git clone https://github.com/how-to-firebase/firelist-react.git
19 | cd firelist-react
20 | git checkout challenge-functions
21 | ```
22 |
23 | ## Edit environment files
24 |
25 | Update the following files with your own project details:
26 |
27 | * `/.firebaserc`
28 | * `/public/environments/environment.dev.js`
29 | * `/public/environments/environment.js`
30 | * `/functions/environments/environment.dev.js`
31 | * `/functions/environments/environment.js`
32 |
33 | ## Run the tests
34 |
35 | Once you're on the branch, make sure to run `yarn` or `npm install` to get your Node.js dependencies.
36 |
37 | Then `cd` into your `functions` directory and run `yarn` or `npm install` again.
38 |
39 | Make sure that you've installed [nvm for Linux/macOS](https://github.com/creationix/nvm), [nvm for Windows](https://github.com/coreybutler/nvm-windows) or some other tool to switch between Node.js versions.
40 |
41 | Use `nvm install 6.14.2` then `nvm use 6.14.2` to switch to Node version 6.14.2.
42 |
43 | The Node version is important to make sure that your tests run in an identical environment to that of the Cloud Functions runtime.
44 |
45 | Then run `yarn test` or `npm test` to run your tests.
46 |
47 | ```text
48 | yarn
49 | cd functions
50 | nvm install 6.14.2
51 | nvm use 6.14.2
52 | node --version //should read out 6.14.2
53 | yarn test
54 | ```
55 |
56 | ## Complete the challenge
57 |
58 | Search the codebase for `Challenge Functions` to find all of the challenges.
59 |
60 | Work through the challenges in order from 01 to 06
61 |
62 |
--------------------------------------------------------------------------------
/cloud-functions-for-firebase/notes.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/how-to-firebase/full-stack-firebase/6f96681d45c1c4892423f9a16cbf0d75cbb9826a/cloud-functions-for-firebase/notes.pdf
--------------------------------------------------------------------------------
/cloud-functions-for-firebase/test-driven-development.md:
--------------------------------------------------------------------------------
1 | Cloud Functions is not for the faint of heart.
2 |
3 | It's extremely powerful.
4 |
5 | It also executes code in a remote environment that you cannot access.
6 |
7 | Therefore, you'll need to adopt test-driven development if you hope to survive the onslaught.
8 |
9 | So let's introduce test-driven development, or TDD for short.
10 |
11 | TDD means that you write code to test code.
12 |
13 | This isn't as hard as you might imagine, and there's plenty of open-source help out there.
14 |
15 | Professionally-produced software is usually written with some form of TDD...
16 |
17 | ...so this isn't a section that you should skip.
18 |
--------------------------------------------------------------------------------
/cloud-functions-for-firebase/walkthrough.md:
--------------------------------------------------------------------------------
1 | # Walkthrough
2 |
3 | ## Open the app
4 |
5 | Open the app at [https://glitch.com/edit/\#!/wind-shrimp](https://glitch.com/edit/#!/wind-shrimp).
6 |
7 | ## Video
8 |
9 | {% embed data="{\"url\":\"https://youtu.be/PxwdciybqyU\",\"type\":\"video\",\"title\":\"Walkthrough: Cloud Functions\",\"description\":\"Full-Stack Firebase:\\n\\nhttps://www.fullstackfirebase.com/cloud-functions-for-firebase/walkthrough\",\"icon\":{\"type\":\"icon\",\"url\":\"https://www.youtube.com/yts/img/favicon\_144-vfliLAfaB.png\",\"width\":144,\"height\":144,\"aspectRatio\":1},\"thumbnail\":{\"type\":\"thumbnail\",\"url\":\"https://i.ytimg.com/vi/PxwdciybqyU/maxresdefault.jpg\",\"width\":1280,\"height\":720,\"aspectRatio\":0.5625},\"embed\":{\"type\":\"player\",\"url\":\"https://www.youtube.com/embed/PxwdciybqyU?rel=0&showinfo=0\",\"html\":\"\",\"aspectRatio\":1.7778}}" %}
10 |
11 |
--------------------------------------------------------------------------------
/cloud-messaging/challenge.md:
--------------------------------------------------------------------------------
1 | # Challenge
2 |
3 | ## Cloud Messaging
4 |
5 | ## Find the repo
6 |
7 | We'll be working on a branch of our [firelist-react](https://github.com/how-to-firebase/firelist-react) repo named [firebase-messaging](https://github.com/how-to-firebase/firelist-react/tree/master).
8 |
9 | ## Localhost installation
10 |
11 | Pull [the repo](https://github.com/how-to-firebase/firelist-react) directly from GitHub...
12 |
13 | ```text
14 | git clone https://github.com/how-to-firebase/firelist-react.git
15 | cd firelist-react
16 | git checkout firebase-messaging
17 | ```
18 |
19 | Once you're on the branch, make sure to run `yarn` or `npm install` to get your Node.js dependencies.
20 |
21 | Then run `yarn start` or `npm run start` to spin up the development server.
22 |
23 | ```text
24 | yarn
25 | yarn start
26 | ```
27 |
28 | ## Complete the challenge
29 |
30 | We'll be editing `./src/components/messaging.js` and `./public/sw.js`.
31 |
32 | Read the comments and complete the steps in those two files.
33 |
34 | ## Notes on sw.js vs firebase-messaging-sw.js
35 |
36 | Firebase Messaging recommends calling your file [firebase-messaging-sw.js](https://firebase.google.com/docs/cloud-messaging/js/receive).
37 |
38 | This is fine as long as you don't care about running your app as a [Progressive Web App](https://developers.google.com/web/progressive-web-apps/) or PWA.
39 |
40 | However! We believe that all apps should be PWAs, so we've configured this project to use the standard `sw.js` filename.
41 |
42 | You'll notice a function in `./src/components/messaging.js` named `registerServiceWorker`
43 |
44 | ```text
45 | async function registerServiceWorker(messaging) {
46 | if ('serviceWorker' in navigator) {
47 | const registration = await navigator.serviceWorker.register('/sw.js');
48 | messaging.useServiceWorker(registration);
49 | }
50 | }
51 | ```
52 |
53 | This function is will register `/sw.js` and then, once that's done, tell messaging to use `/sw.js` instead of `firebase-messaging-sw.js`.
54 |
55 | You can only have one service worker per page. This doesn't work any other way. Trust us. We've tried.
56 |
57 | Yes, you can add all of the service worker functionality that you like into `firebase-messaging-sw.js` and let Firebase Messaging register that file automatically.
58 |
59 | However, this automatic registration will not allow your users to install your app to their homescreen as a PWA... which totally defeats the purpose of a PWA.
60 |
61 | Hence our insistence on using `/sw.js`.
62 |
63 |
--------------------------------------------------------------------------------
/cloud-messaging/introduction.md:
--------------------------------------------------------------------------------
1 | # Introduction
2 |
3 | Cloud Messaging is used for those notifications that pop up in the corner of your Chrome or Firefox browser.
4 |
5 | They're also used to pop native Android and iOS notifications.
6 |
7 | Firebase Cloud Messaging \(FCM\) used to be known as Google Cloud Messaging \(GCM\), and if you're familiar with GCM... well, not much has changed.
8 |
9 | FCM is advertised primarily for use with Android and iOS. The Firebase Console doesn't even have an FCM page on it. There's a Notifications page for Android and iOS that encapsulates FCM functionality, but it's useless for web.
10 |
11 | We'll be interacting directly with the FCM API using a Cloud Function. No Console page is required.
12 |
13 | ## How do I send messages?
14 |
15 | FCM is actually one of the simpler Firebase modules.
16 |
17 | You send messages using Cloud Functions or your own server, and you receive them with a service worker in your browser.
18 |
19 | You can message individual browsers, and you can subscribe a browser to a "topic" so that it can receive bulk messages.
20 |
21 | We'll get into the details later... just know that there's not much to it. You can send messages to your clients either individually or by topic. And the device handles displaying the message. Your work is done.
22 |
23 | ## Why send messages?
24 |
25 | Excessive browser and mobile notifications are obnoxious. Our phones and browsers light up constantly with Twitter notifications trying to drag us back into their app. We disable those notifications pretty aggressively.
26 |
27 | But there's a reason for the flood of alerts. They work. They pull people back into Twitter, Tumblr, and Facebook. And they're super helpful when you miss a bunch of Slack messages or emails from the office.
28 |
29 | You're likely already sending notifications if you develop for Android or iOS. We won't be covering that here, but we'll show you how to send notifications to a web browser. Again, it's not complicated.
30 |
31 |
--------------------------------------------------------------------------------
/cloud-messaging/notes.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/how-to-firebase/full-stack-firebase/6f96681d45c1c4892423f9a16cbf0d75cbb9826a/cloud-messaging/notes.pdf
--------------------------------------------------------------------------------
/cloud-messaging/walkthrough.md:
--------------------------------------------------------------------------------
1 | # Walkthrough
2 |
3 | ## Open the app
4 |
5 | Open the app at [https://fine-ping.glitch.me/](https://fine-ping.glitch.me/).
6 |
7 | ## Open DevTools
8 |
9 | Right-click `inspect element` and select the `Debugger` tab. Then click `command + P` to search for and open two files:
10 |
11 | * `client.js`,
12 | * and `firebase-messaging-sw.js`.
13 |
14 | You'll likely need to open the `Application` tab in DevTools and navigate to the `Service Workers` side tab. Then click the link for `firebase-messaging-sw.js` to inspect it in the `Sources` tab.
15 |
16 | 
17 |
18 | 
19 |
20 | ## Video
21 |
22 | {% embed data="{\"url\":\"https://youtu.be/QaTNDARGH0E\",\"type\":\"video\",\"title\":\"Walkthrough: Cloud Messaging\",\"description\":\"Full-Stack Firebase:\\n\\nhttps://www.fullstackfirebase.com/cloud-messaging/walkthrough\",\"icon\":{\"type\":\"icon\",\"url\":\"https://www.youtube.com/yts/img/favicon\_144-vfliLAfaB.png\",\"width\":144,\"height\":144,\"aspectRatio\":1},\"thumbnail\":{\"type\":\"thumbnail\",\"url\":\"https://i.ytimg.com/vi/QaTNDARGH0E/maxresdefault.jpg\",\"width\":1280,\"height\":720,\"aspectRatio\":0.5625},\"embed\":{\"type\":\"player\",\"url\":\"https://www.youtube.com/embed/QaTNDARGH0E?rel=0&showinfo=0\",\"html\":\"\",\"aspectRatio\":1.7778}}" %}
23 |
24 |
--------------------------------------------------------------------------------
/demo/introduction.md:
--------------------------------------------------------------------------------
1 | # Demo Install
2 |
3 | You can take this course without installing a local copy of the demo.
4 |
5 | You can always come back to this page later if you change your mind :)
6 |
7 | ## Check out the code
8 |
9 | The code can be found on the [How To Firebase GitHub repo](https://github.com/how-to-firebase/fogo).
10 |
11 |
12 | Clone the project to your local filesystem with
13 |
14 | ```bash
15 | git clone https://github.com/how-to-firebase/fogo.git
16 | ```
17 |
18 | You'll find all of the relevant installation instructions inside `fogo/README.md`.
19 |
20 | If you're already a Node.js pro, here's the tldr;
21 |
22 | ```bash
23 | git clone https://github.com/how-to-firebase/fogo.git
24 | cd fogo
25 | yarn
26 | yarn start
27 | ```
28 |
29 | ## Local development
30 |
31 | The startup commands for local development are all combined under `yarn start`.
32 |
33 | `yarn start` will use the Preact CLI to spin up a WebPack compiler and a local development
34 | server with [hot module replacement](https://webpack.js.org/concepts/hot-module-replacement/).
35 |
36 | It should just work... but with all things WebPack, failures can be baffling, so try Googling your
37 | error messages and scan the course comments for hints.
38 |
39 | You should have a working demo in your browser at this point. If not, go through the steps again
40 | and maybe phone a friend.
41 |
--------------------------------------------------------------------------------
/firebase-authentication/challenge.md:
--------------------------------------------------------------------------------
1 | # Challenge
2 |
3 | ## Firebase Authentication
4 |
5 | ## Find the repo
6 |
7 | We'll be working on a branch of our [firelist-react](https://github.com/how-to-firebase/firelist-react) repo named [challenge-authentication](https://github.com/how-to-firebase/firelist-react/tree/challenge-authentication).
8 |
9 | ## Localhost installation
10 |
11 | Pull [the repo](https://github.com/how-to-firebase/firelist-react) directly from GitHub...
12 |
13 | ```text
14 | git clone https://github.com/how-to-firebase/firelist-react.git
15 | cd firelist-react
16 | git checkout challenge-authentication
17 | ```
18 |
19 | ## Edit environment files
20 |
21 | Update the following files with your own project details:
22 |
23 | * `/.firebaserc`
24 | * `/public/environments/environment.dev.js`
25 | * `/public/environments/environment.js`
26 |
27 | ## Start the app
28 |
29 | Once you're on the branch, make sure to run `yarn` or `npm install` to get your Node.js dependencies.
30 |
31 | Then run `yarn start` or `npm run start` to spin up the development server.
32 |
33 | ```text
34 | yarn
35 | yarn start
36 | ```
37 |
38 | ## Complete the challenge
39 |
40 | Search the codebase for `Challenge Authentication` to find all of the challenges.
41 |
42 | We'll be editing `./src/components/authenticate.js` and `./src/index.js`.
43 |
44 | Read the comments and complete the steps in those two files.
45 |
46 |
--------------------------------------------------------------------------------
/firebase-authentication/introduction.md:
--------------------------------------------------------------------------------
1 | # Introduction
2 |
3 | You need Firebase Authentication for two reasons:
4 |
5 | 1. Firebase Security Rules rely on Firebase Authentication
6 | 2. Firebase Authentication is ridiculously easy to use
7 |
8 | ## Firebase Auth + Security Rules
9 |
10 | Firebase needs a security system. In a traditional database you provide your own security using your API server. Since Firebase **is** the API server, it needs a programmable way to control read and write access to your data.
11 |
12 | When users use your client apps to authenticate with Firebase Authentication they receive a [JSON Web Tokens](https://jwt.io/) that will identify them to Firebase's **security rules** system. We'll cover this more later. Just remember that Firebase Authentication will enable your users to interact with the rest of the Firebase platform.
13 |
14 | ## Ease Of Use
15 |
16 | Have you ever implemented your own auth system? Yes? Then you know how challenging it can be. If not... then take my word for it and use an off-the-shelf system. Firebase Authentication provides the following auth methods:
17 |
18 | * Email/password
19 | * Phone
20 | * OAuth 2
21 | * Google
22 | * Facebook
23 | * Twitter
24 | * Github
25 | * Anonymous
26 | * Custom auth
27 |
28 | 
29 |
30 | All of these methods use [JSON Web Tokens](https://jwt.io/), also known as JWTs.
31 |
32 | > JWT is pronounced the same as the English word "jot".
33 |
34 | We'll cover JWTs later. Don't worry. They're simple JSON objects.
35 |
36 | ### Email/Password
37 |
38 | Email/password auth is exactly what it sounds like. You register an email address and a password with Firebase and it keeps track of your user account.
39 |
40 | ### Phone
41 |
42 | Google [acquired Twitter Digits](https://firebase.googleblog.com/2017/01/FabricJoinsGoogle17.html) in early 2017 and rolled their phone authentication into Firebase Authentication. This means that with minimum fuss you can implement a full SMS-based phone auth flow.
43 |
44 | This is particularly great for mobile web apps. Phone authentication is the preferred auth method for many users, especially those outside of the United States.
45 |
46 | ### OAuth 2 \(Google, Facebook, Twitter, Github\)
47 |
48 | OAuth is the fastest auth method, because it relies on accounts that your users already have. Most everyone has either Google, Facebook or Twitter, and developers love Github. OAuth 2 is also the easiest auth flow to implement.
49 |
50 | And all of the OAuth providers support [multi-factor authentication](https://en.wikipedia.org/wiki/Multi-factor_authentication), which we should all be using.
51 |
52 | ## Anonymous Auth
53 |
54 | You may want to interact with a client that hasn't authenticated. If you're developing a shopping cart feature for your app, you may want users to add items to their carts before they've created an account. This is where anonymous auth comes in.
55 |
56 | Without some sort of authentication, there's no way for your server to know who it's talking to.
57 |
58 | Firebase's data is either entirely open or requires authentication. Any private transaction between the Firebase database and a client app requires authentication or it will be public and could be intercepted by a malicious third party.
59 |
60 | There are situations in which you might make your data publicly accessible; however, user transactions with your database are unlikely to fit this model... and that's where anonymous auth comes in.
61 |
62 | We won't cover anonymous auth any further except to show how dead simple it is to execute:
63 |
64 | ```javascript
65 | firebase
66 | .auth()
67 | .signInAnonymously()
68 | .then(successHandler, errorHandler);
69 | ```
70 |
71 | ### Custom Tokens
72 |
73 | Would you like to use a third-party authentication system with Firebase?
74 |
75 | Maybe you'd like to authenticate with your company's existing SAML implementation?
76 |
77 | That's not a problem. We won't cover custom tokens here except to say that you can use your private auth servers to mint Firebase auth tokens that you can then send to your client applications.
78 |
79 | These tokens will allow your client apps to authenticate with Firebase using whatever JWT you create on your server.
80 |
81 | ## Link Multiple Auth Providers
82 |
83 | Linking multiple auth providers is another topic we won't cover here. Just be aware that you can easily [link multiple auth providers to a single account](https://firebase.google.com/docs/auth/web/account-linking).
84 |
85 | For example, your user might register an email/password account and you could prompt her to link her account to Google and Facebook. Your client app can make a couple of easy calls to Firebase Authentication to initiate the linking procedure, and now your user can sign in with Google, Facebook, Twitter or Github.
86 |
87 | Alternatively, if your user signed up with an OAuth account, you can prompt her to register a linked email/password combination.
88 |
89 |
--------------------------------------------------------------------------------
/firebase-authentication/notes.md:
--------------------------------------------------------------------------------
1 | # Notes
2 |
3 | ## Firebase Authentication
4 |
5 | See the [Firebase Authentication docs for web](https://firebase.google.com/docs/auth/web/manage-users).
6 |
7 | ### onAuthStateChanged
8 |
9 | ```javascript
10 | firebase.auth().onAuthStateChanged(currentUser => {
11 | if (currentUser) {
12 | // User is signed in.
13 | } else {
14 | // No user is signed in.
15 | }
16 | });
17 | ```
18 |
19 | ### Register Email/Password
20 |
21 | ```javascript
22 | firebase.auth().createUserWithEmailAndPassword(email, password).catch(function(error) {
23 | // Handle Errors here.
24 | var errorCode = error.code;
25 | var errorMessage = error.message;
26 | // ...
27 | });
28 | ```
29 |
30 | ### Sign In Email/Password
31 |
32 | ```javascript
33 | firebase.auth().signInWithEmailAndPassword(email, password).catch(function(error) {
34 | // Handle Errors here.
35 | var errorCode = error.code;
36 | var errorMessage = error.message;
37 | // ...
38 | });
39 | ```
40 |
41 | ### Create Provider
42 |
43 | Google
44 |
45 | ```javascript
46 | var provider = new firebase.auth.GoogleAuthProvider();
47 | ```
48 |
49 | Facebook
50 |
51 | ```javascript
52 | var provider = new firebase.auth.FacebookAuthProvider();
53 | ```
54 |
55 | Twitter
56 |
57 | ```javascript
58 | var provider = new firebase.auth.TwitterAuthProvider();
59 | ```
60 |
61 | GitHub
62 |
63 | ```javascript
64 | var provider = new firebase.auth.GithubAuthProvider();
65 | ```
66 |
67 | ### OAuth sign in with a provider
68 |
69 | Popup
70 |
71 | ```javascript
72 | firebase.auth().signInWithPopup(provider);
73 | ```
74 |
75 | Redirect
76 |
77 | ```javascript
78 | firebase.auth().signInWithRedirect(provider);
79 | ```
80 |
81 | ### Phone Auth
82 |
83 | First attach a recaptcha using an element ID...
84 |
85 | ```javascript
86 | window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('sign-in-button', {
87 | 'size': 'invisible',
88 | 'callback': function(response) {
89 | // reCAPTCHA solved, allow signInWithPhoneNumber.
90 | onSignInSubmit();
91 | }
92 | });
93 | ```
94 |
95 | ... then capture a phone number from user input and send the sms...
96 |
97 | ```javascript
98 | var phoneNumber = getPhoneNumberFromUserInput();
99 | var appVerifier = window.recaptchaVerifier;
100 | firebase.auth().signInWithPhoneNumber(phoneNumber, appVerifier)
101 | .then(function (confirmationResult) {
102 | // SMS sent. Prompt user to type the code from the message, then sign the
103 | // user in with confirmationResult.confirm(code).
104 | window.confirmationResult = confirmationResult;
105 | }).catch(function (error) {
106 | // Error; SMS not sent
107 | // ...
108 | });
109 | ```
110 |
111 | ...and finally authenticate with the code from user input.
112 |
113 | ```javascript
114 | var code = getCodeFromUserInput();
115 | confirmationResult.confirm(code).then(function (result) {
116 | // User signed in successfully.
117 | var user = result.user;
118 | // ...
119 | }).catch(function (error) {
120 | // User couldn't sign in (bad verification code?)
121 | // ...
122 | });
123 | ```
124 |
125 |
--------------------------------------------------------------------------------
/firebase-authentication/notes.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/how-to-firebase/full-stack-firebase/6f96681d45c1c4892423f9a16cbf0d75cbb9826a/firebase-authentication/notes.pdf
--------------------------------------------------------------------------------
/firebase-authentication/walkthrough.md:
--------------------------------------------------------------------------------
1 | # Walkthrough
2 |
3 | ## Open the app
4 |
5 | Open the app at [fogo.howtofirebase.com](https://fogo.howtofirebase.com/).
6 |
7 | ## Open DevTools
8 |
9 | [Sourcemaps are currently broken in Chrome](https://github.com/webpack/webpack/issues/3165) for Fogo as of July 2018.
10 |
11 | This is best done in Firefox.
12 |
13 | Right-click `inspect element` and select the `Debugger` tab. Then click `command + P` to search for and open two files:
14 |
15 | * `firebase-authentication/src/services/auth.service.js`,
16 | * and `firebase-authentication/src/index.js`.
17 |
18 | 
19 |
20 | 
21 |
22 | ## Video
23 |
24 | {% embed data="{\"url\":\"https://youtu.be/m1rlD-8z3Yo\",\"type\":\"video\",\"title\":\"Walkthrough: Firebase Authentication\",\"description\":\"Full-Stack Firebase: \\n\\nhttps://www.fullstackfirebase.com/firebase-authentication/walk-through\",\"icon\":{\"type\":\"icon\",\"url\":\"https://www.youtube.com/yts/img/favicon\_144-vfliLAfaB.png\",\"width\":144,\"height\":144,\"aspectRatio\":1},\"thumbnail\":{\"type\":\"thumbnail\",\"url\":\"https://i.ytimg.com/vi/m1rlD-8z3Yo/maxresdefault.jpg\",\"width\":1280,\"height\":720,\"aspectRatio\":0.5625},\"embed\":{\"type\":\"player\",\"url\":\"https://www.youtube.com/embed/m1rlD-8z3Yo?rel=0&showinfo=0\",\"html\":\"\",\"aspectRatio\":1.7778}}" %}
25 |
26 |
--------------------------------------------------------------------------------
/firebase-console/introduction.md:
--------------------------------------------------------------------------------
1 | # Introduction
2 |
3 | We'll kick this party off with a quick run down of the Firebase Console.
4 |
5 | It's how you'll interact with most of the Firebase features. You'll need your Console to configure your Firebase services and watch data flow through your project.
6 |
7 | Most of the Console's functions are also accessible via the Firebase Tools command-line interface, or CLI; however, we always have our Firebase Console open in a browser tab whenever we're developing on Firebase. So make good friends with your Firebase Console and it will help carry your app to serverless glory.
8 |
9 |
--------------------------------------------------------------------------------
/firebase-hosting/challenge.md:
--------------------------------------------------------------------------------
1 | # Challenge
2 |
3 | ## Firebase Hosting
4 |
5 | ## Find the repo
6 |
7 | We'll be working on the [master branch](https://github.com/how-to-firebase/firelist-react) of our [firelist-react](https://github.com/how-to-firebase/firelist-react) repo.
8 |
9 | ## Localhost installation
10 |
11 | Pull [the repo](https://github.com/how-to-firebase/firelist-react) directly from GitHub...
12 |
13 | ```text
14 | git clone https://github.com/how-to-firebase/firelist-react.git
15 | cd firelist-react
16 | git checkout master
17 | ```
18 |
19 | ## Edit environment files
20 |
21 | Update the following files with your own project details:
22 |
23 | * `/.firebaserc`
24 | * `/functions/environments/environment.dev.js`
25 | * `/functions/environments/environment.js`
26 | * `/public/environments/environment.dev.js`
27 | * `/public/environments/environment.js`
28 |
29 | ## Build the app
30 |
31 | Once you're on the branch, make sure to run `yarn build` or `npm install` to get your Node.js dependencies.
32 |
33 | Build the app with `yarn build` or `yarn build:windows`.
34 |
35 | ## Inspect firebase.json
36 |
37 | Read through `/firebase.json` and try to understand the settings.
38 |
39 | ## Deploy the app
40 |
41 | Just run `yarn deploy`!
42 |
43 | Check out `/package.json` and the `scripts` attribute to see what scripts are available and what they do.
44 |
45 |
--------------------------------------------------------------------------------
/firebase-hosting/introduction.md:
--------------------------------------------------------------------------------
1 | # Introduction
2 |
3 | Every web app needs to serve static content. Static content includes your HTML, JavaScript and CSS files as well as any images or other assets that your client-side app needs to run.
4 |
5 | There are plenty of easy ways to serve up static files; but since every app needs to do it, Firebase has an integrated static file hosting solution.
6 |
7 | ## Advantages of Firebase Hosting
8 |
9 | Firebase Hosting is fully integrated with the rest of the Firebase platform. You can deploy easily from the command line. You can see those deploys on the Firebase Console and roll back to earlier versions if you break something.
10 |
11 | Hosting supports URL redirects, URL rewrites, control over headers and default HTTP2 support.
12 |
13 | You can easily connect a custom domain, and Firebase Hosting will automatically provision your SSL certificate, so you will always be protected by HTTPS.
14 |
15 | And the icing on the cake is Firebase Hosting's integration with Cloud Functions. You can, with a couple of lines of configuration, redirect a URL on your Hosting domain to any of your HTTP-triggered Cloud Functions. Now you can serve up dynamic content in addition to your static files!
16 |
17 | ## Disadvantages of Firebase Hosting
18 |
19 | There aren't any. The headline is misleading.
20 |
21 |
--------------------------------------------------------------------------------
/firebase-hosting/notes.md:
--------------------------------------------------------------------------------
1 | # Notes
2 |
3 | ## Firebase Hosting
4 |
5 | See the [Firebase Hosting doc for web](https://firebase.google.com/docs/cloud-messaging/js/client).
6 |
7 | ### Redirects
8 |
9 | ```javascript
10 | "hosting": {
11 | // Add the "redirects" section within "hosting"
12 | "redirects": [ {
13 | "source" : "/foo",
14 | "destination" : "/bar",
15 | "type" : 301
16 | }, {
17 | "source" : "/firebase/*",
18 | "destination" : "https://firebase.google.com",
19 | "type" : 302
20 | } ]
21 | }
22 | ```
23 |
24 | ### Rewrites
25 |
26 | ```javascript
27 | "hosting": {
28 | // Add the "rewrites" section within "hosting"
29 | "rewrites": [ {
30 | "source": "**",
31 | "destination": "/index.html"
32 | } ]
33 | }
34 | ```
35 |
36 | ### Headers
37 |
38 | ```javascript
39 | "hosting": {
40 | // Add the "headers" section within "hosting".
41 | "headers": [ {
42 | "source" : "**/*.@(eot|otf|ttf|ttc|woff|font.css)",
43 | "headers" : [ {
44 | "key" : "Access-Control-Allow-Origin",
45 | "value" : "*"
46 | } ]
47 | }, {
48 | "source" : "**/*.@(jpg|jpeg|gif|png)",
49 | "headers" : [ {
50 | "key" : "Cache-Control",
51 | "value" : "max-age=7200"
52 | } ]
53 | }, {
54 | // Sets the cache header for 404 pages to cache for 5 minutes
55 | "source" : "404.html",
56 | "headers" : [ {
57 | "key" : "Cache-Control",
58 | "value" : "max-age=300"
59 | } ]
60 | } ]
61 | }
62 | ```
63 |
64 | ### Connect a Cloud Function
65 |
66 | ```javascript
67 | {
68 | "hosting": {
69 | "public": "public",
70 |
71 | // Add the following rewrites section *within* "hosting"
72 | "rewrites": [ {
73 | "source": "/bigben", "function": "bigben"
74 | } ]
75 |
76 | }
77 | }
78 | ```
79 |
80 |
--------------------------------------------------------------------------------
/firebase-hosting/notes.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/how-to-firebase/full-stack-firebase/6f96681d45c1c4892423f9a16cbf0d75cbb9826a/firebase-hosting/notes.pdf
--------------------------------------------------------------------------------
/firebase-hosting/walkthrough.md:
--------------------------------------------------------------------------------
1 | # Walkthrough
2 |
3 | ## Open the app
4 |
5 | Open the app at [https://glitch.com/edit/\#!/ripe-knife](https://glitch.com/edit/#!/ripe-knife).
6 |
7 | ## Video
8 |
9 | {% embed data="{\"url\":\"https://youtu.be/SX5kh7J1LsE\",\"type\":\"video\",\"title\":\"Walkthrough: Firebase Hosting\",\"description\":\"Full-Stack Firebase:\\n\\nhttps://www.fullstackfirebase.com/firebase-hosting/walkthrough\",\"icon\":{\"type\":\"icon\",\"url\":\"https://www.youtube.com/yts/img/favicon\_144-vfliLAfaB.png\",\"width\":144,\"height\":144,\"aspectRatio\":1},\"thumbnail\":{\"type\":\"thumbnail\",\"url\":\"https://i.ytimg.com/vi/SX5kh7J1LsE/maxresdefault.jpg\",\"width\":1280,\"height\":720,\"aspectRatio\":0.5625},\"embed\":{\"type\":\"player\",\"url\":\"https://www.youtube.com/embed/SX5kh7J1LsE?rel=0&showinfo=0\",\"html\":\"\",\"aspectRatio\":1.7778}}" %}
10 |
11 |
--------------------------------------------------------------------------------
/firebase-storage/challenge.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Firebase Storage Challenge
3 | ---
4 |
5 | # Challenge
6 |
7 | ## Firebase Storage
8 |
9 | ## Find the repo
10 |
11 | We'll be working on a branch of our [firelist-react](https://github.com/how-to-firebase/firelist-react) repo named [challenge-storage](https://github.com/how-to-firebase/firelist-react/tree/challenge-storage).
12 |
13 | ## Localhost installation
14 |
15 | Pull [the repo](https://github.com/how-to-firebase/firelist-react) directly from GitHub...
16 |
17 | ```text
18 | git clone https://github.com/how-to-firebase/firelist-react.git
19 | cd firelist-react
20 | git checkout challenge-storage
21 | ```
22 |
23 | ## Edit environment files
24 |
25 | Update the following files with your own project details:
26 |
27 | * `/.firebaserc`
28 | * `/public/environments/environment.dev.js`
29 | * `/public/environments/environment.js`
30 | * `/functions/environments/environment.dev.js`
31 | * `/functions/environments/environment.js`
32 |
33 | ## Deploy Cloud Functions
34 |
35 | If you had some trouble deploying Cloud Functions earlier, make sure to deploy the correct functions now.
36 |
37 | Run `yarn deploy:functions` to deploy valid versions of each function up to your Firebase project.
38 |
39 | ## Start the app
40 |
41 | Once you're on the branch, make sure to run `yarn` or `npm install` to get your Node.js dependencies.
42 |
43 | Then run `yarn start` or `npm run start` to spin up the development server.
44 |
45 | ```text
46 | yarn
47 | yarn start
48 | ```
49 |
50 | ## Complete the challenge
51 |
52 | Search the codebase for `Challenge Storage` to find all of the challenges.
53 |
54 | Read the comments and complete the steps in those files.
55 |
56 | * `src/storage/delete-image.js`
57 | * `src/storage/get-upload-observable.js`
58 |
59 |
--------------------------------------------------------------------------------
/firebase-storage/introduction.md:
--------------------------------------------------------------------------------
1 | # Introduction
2 |
3 | Every image that you upload online has to get stored somewhere, and cloud storage providers such as Amazon and Google Cloud will store those files as "objects" in "buckets".
4 |
5 | The Firebase Realtime Database and Cloud Firestore are great for storing data, but they're not so good with files. Google Cloud Storage, heretofore referred to as Cloud Storage, is built to store and serve these files.
6 |
7 | Firebase Storage is a front for Cloud Storage... an extremely useful front.
8 |
9 | ## The old file-upload pattern
10 |
11 | Browsers are great at uploading files, but files are often too big to send over a single HTTP POST, so they're typically streamed to a server. This streaming happens as a series of chunks which the server has to listen for, waiting patiently until the total size of the chunks adds up to the expected file size. The server can then take the file that it has assembled from a bunch of chunks and stream it up to Cloud Storage... again, in a series of chunks.
12 |
13 | We've written plenty of file streaming servers, and they're a pain in the neck.
14 |
15 | ## Firebase Storage saves the day
16 |
17 | The old file-upload pattern requires a sophisticated server. And Firebase is all about getting rid of your servers.
18 |
19 | Firebase Storage enables you to upload files directly from a browser to Cloud Storage. Firebase Storage handles all of the servers and all of the streaming, leaving you with a simple JavaScript interface.
20 |
21 | It seems like a small feature.
22 |
23 | Firebase Storage is tiny.
24 |
25 | All it does is upload files.
26 |
27 | But it's hiding a ton of complexity that you'd have to code yourself, so it's a massive win.
28 |
29 | ## It's just a bucket
30 |
31 | Cloud Storage treats each bucket as just that, a bucket.
32 |
33 | Cloud Storage does not have a concept of folders.
34 |
35 | But you **can** put forward slashes in your filenames, which Firebase Storage will treat as a file path.
36 |
37 | For example, we've created a Firebase project named `Quiver Four`; therefore, Firebase Storage automatically creates a Cloud Storage bucket named `quiver-four.appspot.com`.
38 |
39 | Let's upload a file to `howtofirebase/uploads/enable-firestore.png`:
40 |
41 | ```javascript
42 | function uploadFile(file) {
43 | return firebase
44 | .storage()
45 | .ref()
46 | .child('howtofirebase/uploads/enable-firestore.png')
47 | .put(file)
48 | .then(snapshot => {
49 | // snapshot represents the uploaded file
50 | });
51 | }
52 | ```
53 |
54 | And the Firebase Console pretends that the file is in a nested folder!
55 |
56 | 
57 |
58 | Cloud Storage pretends that it's in a folder as well:
59 |
60 | 
61 |
62 | But then we pulled the file details down using the Cloud Storage SDK and pushed them up to Firestore. Notice that file's name attribute is `howtofirebase/uploads/enable-firestore.png`.
63 |
64 | 
65 |
66 | ## Cloud Storage SDK
67 |
68 | Firebase Storage does not have it's own Node.js SDK. It's a browser-only system.
69 |
70 | But do not despair! Since these files are merely Cloud Storage objects in a Cloud Storage bucket, we can use the Cloud Storage SDK to interact with them in Node.js.
71 |
72 | And we can get Cloud Storage SDK bucket references straight from the Firebase Admin SDK in Node.js!
73 |
74 | ```javascript
75 | const admin = require("firebase-admin");
76 |
77 | const serviceAccount = require("path/to/serviceAccountKey.json");
78 |
79 | admin.initializeApp({
80 | credential: admin.credential.cert(serviceAccount),
81 | storageBucket: "quiver-foure.appspot.com"
82 | });
83 |
84 | const bucket = admin.storage().bucket();
85 | // 'bucket' is a Cloud Storage bucket instance
86 | ```
87 |
88 | `bucket` is an object defined by the [@google-cloud/storage library](https://cloud.google.com/nodejs/docs/reference/storage/1.5.x/Bucket) for Node.js. The GCP libraries feel different from the Firebase libraries, mostly because the docs look different. But don't be afraid of GCP. It gives you much finer-grained control over its features than Firebase does.
89 |
90 |
--------------------------------------------------------------------------------
/firebase-storage/notes.md:
--------------------------------------------------------------------------------
1 | # Notes
2 |
3 | ## Firebase Storage
4 |
5 | See the [Firebase Storage docs for web](https://firebase.google.com/docs/storage/web/start).
6 |
7 | ### Create a ref
8 |
9 | ```javascript
10 | var storageRef = firebase.storage().ref();
11 | const fileRef = storageRef.child('/some/file/path.jpg);
12 | ```
13 |
14 | ### Navigate
15 |
16 | ```javascript
17 | // Points to the root reference
18 | var storageRef = firebase.storage().ref();
19 |
20 | // Points to 'images'
21 | var imagesRef = storageRef.child('images');
22 |
23 | // Points to 'images/space.jpg'
24 | // Note that you can use variables to create child values
25 | var fileName = 'space.jpg';
26 | var spaceRef = imagesRef.child(fileName);
27 |
28 | // File path is 'images/space.jpg'
29 | var path = spaceRef.fullPath;
30 |
31 | // File name is 'space.jpg'
32 | var name = spaceRef.name;
33 |
34 | // Points to 'images'
35 | var imagesRef = spaceRef.parent;
36 | ```
37 |
38 | ### Upload file
39 |
40 | ```javascript
41 | // Create file metadata including the content type
42 | var metadata = {
43 | contentType: 'image/jpeg',
44 | };
45 |
46 | // Upload the file and metadata
47 | var uploadTask = storageRef.child('images/mountains.jpg').put(file, metadata);
48 | ```
49 |
50 | ### Full example
51 |
52 | ```javascript
53 | function uploadFile(file) {
54 | // Create the file metadata
55 | var metadata = {
56 | contentType: 'image/jpeg',
57 | };
58 |
59 | // Upload file and metadata to the object 'images/mountains.jpg'
60 | var uploadTask = storageRef.child('images/' + file.name).put(file, metadata);
61 |
62 | // Listen for state changes, errors, and completion of the upload.
63 | uploadTask.on(
64 | firebase.storage.TaskEvent.STATE_CHANGED, // or 'state_changed'
65 | function(snapshot) {
66 | // Get task progress, including the number of bytes uploaded and the total number of bytes to be uploaded
67 | var progress = snapshot.bytesTransferred / snapshot.totalBytes * 100;
68 | console.log('Upload is ' + progress + '% done');
69 | switch (snapshot.state) {
70 | case firebase.storage.TaskState.PAUSED: // or 'paused'
71 | console.log('Upload is paused');
72 | break;
73 | case firebase.storage.TaskState.RUNNING: // or 'running'
74 | console.log('Upload is running');
75 | break;
76 | }
77 | },
78 | function(error) {
79 | // Errors list: https://firebase.google.com/docs/storage/web/handle-errors
80 | switch (error.code) {
81 | case 'storage/unauthorized':
82 | // User doesn't have permission to access the object
83 | break;
84 |
85 | case 'storage/canceled':
86 | // User canceled the upload
87 | break;
88 |
89 | case 'storage/unknown':
90 | // Unknown error occurred, inspect error.serverResponse
91 | break;
92 | }
93 | },
94 | function() {
95 | // Upload completed successfully, now we can get the download URL
96 | var downloadURL = uploadTask.snapshot.downloadURL;
97 | }
98 | );
99 | }
100 | ```
101 |
102 | ### Download file
103 |
104 | ```javascript
105 | // Create a reference to the file we want to download
106 | var starsRef = storageRef.child('images/stars.jpg');
107 |
108 | // Get the download URL
109 | starsRef.getDownloadURL().then(function(url) {
110 | // Insert url into an tag to "download"
111 | }).catch(function(error) {
112 |
113 | // A full list of error codes is available at
114 | // https://firebase.google.com/docs/storage/web/handle-errors
115 | switch (error.code) {
116 | case 'storage/object_not_found':
117 | // File doesn't exist
118 | break;
119 |
120 | case 'storage/unauthorized':
121 | // User doesn't have permission to access the object
122 | break;
123 |
124 | case 'storage/canceled':
125 | // User canceled the upload
126 | break;
127 |
128 | ...
129 |
130 | case 'storage/unknown':
131 | // Unknown error occurred, inspect the server response
132 | break;
133 | }
134 | });
135 | ```
136 |
137 | ### Set metadata
138 |
139 | ```javascript
140 | // Create a reference to the file whose metadata we want to change
141 | var forestRef = storageRef.child('images/forest.jpg');
142 |
143 | // Create file metadata to update
144 | var newMetadata = {
145 | cacheControl: 'public,max-age=300',
146 | contentType: 'image/jpeg',
147 | contentLanguage: null,
148 | customMetadata: {
149 | whatever: 'we feel like',
150 | },
151 | };
152 |
153 | // Update metadata properties
154 | forestRef
155 | .updateMetadata(newMetadata)
156 | .then(function(metadata) {
157 | // Updated metadata for 'images/forest.jpg' is returned in the Promise
158 | })
159 | .catch(function(error) {
160 | // Uh-oh, an error occurred!
161 | });
162 | ```
163 |
164 |
--------------------------------------------------------------------------------
/firebase-storage/notes.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/how-to-firebase/full-stack-firebase/6f96681d45c1c4892423f9a16cbf0d75cbb9826a/firebase-storage/notes.pdf
--------------------------------------------------------------------------------
/firebase-storage/security-rules.md:
--------------------------------------------------------------------------------
1 | # Security Rules
2 |
3 | ## Security Rules
4 |
5 | ## Firebase Storage
6 |
7 | Firebase Storage exposes quite a bit of functionality to the public, so you'll need to write some security rules.
8 |
9 | Like Firestore, Firebase Storage uses Firebase's new security rules syntax.
10 |
11 | ### Review Firestore security rules
12 |
13 | The best way to understand Firebase Storage security rules is to read up on [Firestore security rules](https://how-to-firebase.gitbooks.io/full-stack-firebase/content/cloud-firestore/security-rules.html). They're basically the same.
14 |
15 | ### The basics
16 |
17 | The basic rules look something like this:
18 |
19 | ```text
20 | // Only authenticated users can read or write to the bucket
21 | service firebase.storage {
22 | match /b/{bucket}/o {
23 | match /{allPaths=**} {
24 | allow read, write: if request.auth != null;
25 | }
26 | }
27 | }
28 | ```
29 |
30 | Let's break these rules down line-by-line.
31 |
32 | **service firebase.storage** - defines the service, in this case it's firebase.storage
33 |
34 | **match /b/{bucket}/o** - defines the bucket; the `{bucket}` clause indicates that these rules apply to all Cloud Storage buckets on the project
35 |
36 | **match /{allPaths=\*\*}** - creates a new rules block to apply to all paths
37 |
38 | **allow read, write: if requests.auth != true ;** - allows read/write access for all authenticated sessions
39 |
40 | ### Match blocks
41 |
42 | Match blocks are identical to [those of Firestore](https://how-to-firebase.gitbooks.io/full-stack-firebase/content/cloud-firestore/security-rules.html).
43 |
44 | Of course, instead of matching collections and documents, you're matching folders and storage objects. But that's the only difference.
45 |
46 | Let's write a match block for a folder structure like this: `/user/{userId}/path/to/file.txt`
47 |
48 | ```text
49 | service firebase.storage {
50 | match /b/{bucket}/o {
51 | match /user/{userId}/{allPaths=**} {
52 | allow read, write: if request.auth.uid == userId;
53 | }
54 | }
55 | }
56 | ```
57 |
58 | And, like Firestore, match blocks can be nested... if you need it.
59 |
60 | Firebase Storage security rules tend to be a bit simpler than Firestore's.
61 |
62 | ### Rule types
63 |
64 | Firebase Storage supports `read` and `write`. That's it. This is a break from Cloud Firestore which supports other sub-types. In this case you're either reading or writing.
65 |
66 | ### Wildcard variables
67 |
68 | Wildcards work just like those in Firestore. You can place them at will and override them as needed. You'll also want to be careful to use the `{someWildcard=**}` syntax when you want your rules to cascade; otherwise, they won't apply to nested folders.
69 |
70 | The following example secures a dropbox-style pattern where users can upload to an uploads folder at `/user/uploads/{userId}/uploaded-file.jpg` but can only read from `/user/thumbnails/{userId}/thumbnail.jpg`.
71 |
72 | ```text
73 | service firebase.storage {
74 | match /b/{bucket}/o {
75 | match /user/ {
76 | match /thumbnails/{userId}/{thumbnail} {
77 | allow read: if request.auth.uid == userId;
78 | }
79 | match /uploads/{userId}/{upload} {
80 | allow write: if request.auth.uid == userId;
81 | }
82 | }
83 | }
84 | }
85 | ```
86 |
87 | ### Request variables
88 |
89 | Rule conditions have access to a `request` object that represents that incoming request. You'll be using the `request` object for most rule conditions.
90 |
91 | The fields of most interest are `request.auth.uid` and `request.auth.token`, which contains the user's JWT.
92 |
93 | ### Resource variables
94 |
95 | Rule conditions also have access to a `resource` object. In Firestore this object refers to the pre-write state of the document, but in Firebase Storage this is the object being uploaded, downloaded, modified or deleted.
96 |
97 | Here's a sample `resource` object that you may find handy:
98 |
99 | ```javascript
100 | {
101 | "name": "howtofirebase/uploads/locked-mode.png",
102 | "bucket": "quiver-four.appspot.com",
103 | "generation": "1517664154693678",
104 | "metageneration": "1",
105 | "size": "138099",
106 | "timeCreated": "2018-02-03T13:22:34.676Z",
107 | "updated": "2018-02-03T13:22:34.676Z",
108 | "md5Hash": "Yzg3ZGNlZDVjODZiYzAyNGU4NTljYTU2MDdlZDMwMjk=",
109 | "crc32c": "QK5Kyw==",
110 | "etag": "CK7g0MbridkCEAE=",
111 | "contentDisposition": "inline; filename*=utf-8''locked-mode.png",
112 | "contentEncoding": "gzip",
113 | "contentLanguage": "en",
114 | "contentType": "image/png",
115 | "metadata": {
116 | "firebaseStorageDownloadTokens": "c7dfc4c3-0d91-4e1a-b6a1-d4e03a320ef1"
117 | }
118 | }
119 | ```
120 |
121 | ### Read the docs
122 |
123 | It's been said before and we'll say it again. Read the docs.
124 |
125 | The highlights:
126 |
127 | * [the Request object](https://firebase.google.com/docs/reference/security/storage/#request)
128 | * [the Resource object](https://firebase.google.com/docs/reference/security/storage/#resource)
129 | * [Data types](https://firebase.google.com/docs/reference/security/storage/#data_types)
130 |
131 |
--------------------------------------------------------------------------------
/firebase-storage/walkthrough.md:
--------------------------------------------------------------------------------
1 | # Walkthrough
2 |
3 | ## Open the app
4 |
5 | Open the app at [fogo.howtofirebase.com](https://fogo.howtofirebase.com/).
6 |
7 | ## Open DevTools
8 |
9 | [Sourcemaps are currently broken in Chrome](https://github.com/webpack/webpack/issues/3165) for Fogo as of July 2018.
10 |
11 | This is best done in Firefox.
12 |
13 | Right-click `inspect element` and select the `Debugger` tab. Then click `command + P` to search for and open one file:
14 |
15 | * `storage-uploader/src/services/storage.service.js`.
16 |
17 | 
18 |
19 | ## Video
20 |
21 | {% embed data="{\"url\":\"https://youtu.be/cuHTeqwbr44\",\"type\":\"video\",\"title\":\"Walkthrough: Firebase Storage\",\"description\":\"Full-Stack Firebase:\\n\\nhttps://www.fullstackfirebase.com/firebase-storage/walkthrough\",\"icon\":{\"type\":\"icon\",\"url\":\"https://www.youtube.com/yts/img/favicon\_144-vfliLAfaB.png\",\"width\":144,\"height\":144,\"aspectRatio\":1},\"thumbnail\":{\"type\":\"thumbnail\",\"url\":\"https://i.ytimg.com/vi/cuHTeqwbr44/maxresdefault.jpg\",\"width\":1280,\"height\":720,\"aspectRatio\":0.5625},\"embed\":{\"type\":\"player\",\"url\":\"https://www.youtube.com/embed/cuHTeqwbr44?rel=0&showinfo=0\",\"html\":\"\",\"aspectRatio\":1.7778}}" %}
22 |
23 |
--------------------------------------------------------------------------------
/firebase-tools/introduction.md:
--------------------------------------------------------------------------------
1 | # Introduction
2 |
3 | The Firebase Console handles most administrative functions, but it doesn't deploy code, and there are some admin functions that don't have console dashboards yet.
4 |
5 | That's where Firebase Tools comes in.
6 |
7 | Firebase Tools is a command-line interface or CLI that uses Node.js to administer your Firebase projects. It has a ton of capabilities, but we'll stick to the basics.
8 |
9 |
--------------------------------------------------------------------------------
/introduction/downloadable-notes.md:
--------------------------------------------------------------------------------
1 | # Downloadable Notes
2 |
3 | 
4 |
5 | * [All PDFs Zipped](https://github.com/how-to-firebase/full-stack-firebase/raw/master/notes.zip)
6 | * [All notes in a single, combined PDF](https://github.com/how-to-firebase/full-stack-firebase/raw/master/notes/full-stack-firebase-notes-combined.pdf)
7 | * [Individual note files](https://github.com/how-to-firebase/full-stack-firebase/tree/master/notes)
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/introduction/full-stack-firebase.md:
--------------------------------------------------------------------------------
1 | # Full-Stack Firebase
2 |
3 | ## Learn Production-Worthy Firebase
4 |
5 | {% embed data="{\"url\":\"https://youtu.be/fQosnpJ4x-Q\",\"type\":\"video\",\"title\":\"Full-Stack Firebase Promo\",\"description\":\"Video Course:\\n\\nhttps://www.udemy.com/full-stack-firebase/?couponCode=FULLSTACK2018\\n\\neBook:\\n\\nhttps://www.fullstackfirebase.com/\",\"icon\":{\"type\":\"icon\",\"url\":\"https://www.youtube.com/yts/img/favicon\_144-vfliLAfaB.png\",\"width\":144,\"height\":144,\"aspectRatio\":1},\"thumbnail\":{\"type\":\"thumbnail\",\"url\":\"https://i.ytimg.com/vi/fQosnpJ4x-Q/mqdefault.jpg\",\"width\":320,\"height\":180,\"aspectRatio\":0.5625},\"embed\":{\"type\":\"player\",\"url\":\"https://www.youtube.com/embed/fQosnpJ4x-Q?rel=0&showinfo=0\",\"html\":\"\",\"aspectRatio\":1.7778},\"caption\":\"Full-Stack Firebase on Udemy\"}" %}
6 |
7 | ## Available on Udemy
8 |
9 | 
10 |
11 | We've launched [Full-Stack Firebase on Udemy](https://www.udemy.com/full-stack-firebase/?couponCode=FULLSTACK2018) for the full video experience.
12 |
13 | The Udemy course features 2.5 hours of tightly-edited video walkthroughs. It is the absolute fastest, easiest way to learn Firebase. We've condensed everything on FullStackFirebase.com into video form with free instructor Q&A.
14 |
15 | ## Newsletter
16 |
17 | 
18 |
19 | [Sign up for email updates](http://eepurl.com/ceGkov) 💌
20 |
21 | We'll send you some "getting started" emails. From there on out, we email with a light touch 👍
22 |
23 | ## GitBook vs GitHub
24 |
25 | Read the GitBook or the GitHub repo:
26 |
27 | * [GitBook](https://www.fullstackfirebase.com/): A luxurious reading experience
28 | * [GitHub](https://github.com/how-to-firebase/full-stack-firebase): The delightful and gory details
29 |
30 | ## Beginners Welcome!
31 |
32 | You'll need to know JavaScript. If you're weak on JavaScript... this may not be the course for you.
33 |
34 | Check out the Prerequisites chapter for all of the details.
35 |
36 | You don't need to know anything about Firebase to get started. Just be patient and move slowly through the material.
37 |
38 | If you're already adept with Firebase, then please jump around! The more advanced modules later in the course will be of particular interest.
39 |
40 | We'll cover integration for Angular and React. The Firebase SDK is all vanilla JavaScript, so if you can integrate with Angular and React, you should be able to integrate with any other modern framework.
41 |
42 | ## Modules
43 |
44 | This course consists of a bunch of modules, including:
45 |
46 | * Firebase Console
47 | * Firebase Authentication
48 | * Cloud Firestore
49 | * Realtime Database
50 | * Cloud Functions
51 | * Firebase Storage
52 | * Cloud Messaging
53 | * Firebase Hosting
54 |
55 | ## Module Structure
56 |
57 | Each module will have the following parts:
58 |
59 | * Introduction
60 | * Feature walk-through\(s\)
61 | * Exercise\(s\)
62 | * Downloadable notes
63 |
64 | Some modules will build on each other, so skip around carefully 😉
65 |
66 | ## What to expect
67 |
68 | * Opinionated code
69 | * Angular and React integrations
70 | * You'll need a Firebase account
71 |
72 | We write opinionated code, and we like our courses opinionated as well.
73 |
74 | If you're not familiar with Angular or React, do not worry. The markup and JavaScript is easy enough to read, and we'll stick to vanilla JS as much as possible.
75 |
76 | Firebase's [free Spark plan](https://firebase.google.com/pricing/) is **very generous**. Firebase Functions requires a paid Blaze plan _**IF**_ you want to make external HTTP calls. Otherwise, you can skate by on Spark.
77 |
78 | ## This course is not...
79 |
80 | * 100% framework agnostic
81 | * Exhaustive documentation
82 | * Constantly updated
83 |
84 | Firebase is framework-agnostic... but good luck writing a modern web application without some sort of templating framework.
85 |
86 | We'll reference the [Firebase Docs](https://firebase.google.com/docs/) quite a bit throughout. We will try to duplicate them.
87 |
88 | Firebase changes. A lot. The docs are canonical. Use them. We'll do our best to update this content, but staying 100% current would be a full-time job.
89 |
90 | Have you found an error or a bug? Don't hesitate to [file an issue ](https://github.com/how-to-firebase/full-stack-firebase/issues) or make pull requests 💕
91 |
92 |
--------------------------------------------------------------------------------
/introduction/links.md:
--------------------------------------------------------------------------------
1 | # Links
2 |
3 | Read the online book at [FullStackFirebase.com](https://www.fullstackfirebase.com/)
4 |
5 | Check out our [Glitch.com demo library](https://glitch.com/@deltaepsilon)
6 |
7 | Our [How To Firebase GitHub Org](https://github.com/how-to-firebase) hosts all of our code:
8 |
9 | * [full-stack-firebase](https://github.com/how-to-firebase/full-stack-firebase)
10 | * [firelist-react](https://github.com/how-to-firebase/firelist-react)
11 | * [firelist-angular](https://github.com/how-to-firebase/firelist-angular)
12 | * [tutorials](https://github.com/how-to-firebase/tutorials)
13 | * [fogo](https://github.com/how-to-firebase/fogo)
14 |
15 | ## Introduction
16 |
17 | [Write your first query](https://glitch.com/edit/#!/coordinated-freighter)
18 |
19 | ## Firebase Console
20 |
21 | [Browser configuration](https://glitch.com/edit/#!/malachite-engine)
22 |
23 | [Node.js configuration](https://glitch.com/edit/#!/thread-asphalt)
24 |
25 | ## Firebase Tools
26 |
27 | [Firebase Tools](https://glitch.com/edit/#!/somber-binder)
28 |
29 | ## Firebase Authentication
30 |
31 | [Fogo](https://fogo.howtofirebase.com/login)
32 |
33 | [Authentication Notes](https://github.com/how-to-firebase/full-stack-firebase/raw/master/firebase-authentication/notes.pdf)
34 |
35 | ## Cloud Firestore
36 |
37 | [Where and orderBy](https://glitch.com/edit/#!/earthy-rhinoceros)
38 |
39 | [Firestore Notes](https://github.com/how-to-firebase/full-stack-firebase/raw/master/cloud-firestore/notes.pdf)
40 |
41 | ## Realtime Database
42 |
43 | [Firebase Chat](https://glitch.com/edit/#!/truth-spleen)
44 |
45 | [Realtime Database Notes](https://github.com/how-to-firebase/full-stack-firebase/raw/master/realtime-database/notes.pdf)
46 |
47 | ## Cloud Functions for Firebase
48 |
49 | [Firebase Chat with Functions](https://glitch.com/edit/#!/merciful-quicksand)
50 |
51 | [Cloud Functions Notes](https://github.com/how-to-firebase/full-stack-firebase/raw/master/cloud-functions-for-firebase/notes.pdf)
52 |
53 | ## Firebase Storage
54 |
55 | [Fogo](https://fogo.howtofirebase.com/login)
56 |
57 | [Storage Notes](https://github.com/how-to-firebase/full-stack-firebase/raw/master/firebase-storage/notes.pdf)
58 |
59 | ## Cloud Messaging
60 |
61 | [Firebase Cloud Messaging walkthrough](https://glitch.com/edit/#!/fine-ping)
62 |
63 | [Cloud Messaging Notes](https://github.com/how-to-firebase/full-stack-firebase/raw/master/cloud-messaging/notes.pdf)
64 |
65 | ## Firebase Hosting
66 |
67 | [Firebase Hosting walkthrough](https://glitch.com/edit/#!/ripe-knife?path=firebase.json:3:23)
68 |
69 | [Hosting Notes](https://github.com/how-to-firebase/full-stack-firebase/raw/master/firebase-hosting/notes.pdf)
70 |
71 | ## Next Steps
72 |
73 | [Firebase Community Slack](https://firebase.community/)
74 |
75 | [@ChrisEsplin \(Twitter\)](https://twitter.com/chrisesplin)
76 |
77 | [@JuarezPAF \(Twitter\)](https://twitter.com/juarezpaf)
78 |
79 |
--------------------------------------------------------------------------------
/introduction/overview-and-structure.md:
--------------------------------------------------------------------------------
1 | # Overview & Structure
2 |
3 | This course consists of a bunch of modules, including:
4 |
5 | * Firebase Console
6 | * Firebase Authentication
7 | * Firestore
8 | * Realtime Database
9 | * Cloud Functions for Firebase
10 | * Firebase Storage
11 | * Cloud Messaging
12 | * Firebase Hosting
13 |
14 | ## Modules
15 |
16 | Some of these modules are **much** larger than others.
17 |
18 | For instance, we'll breeze through Authentication, Storage, Hosting and Messaging. These topics are isolated and straightforward. They don't require much decision-making. We need to get comfortable with how these services fit into a production-worthy Firebase architecture, and then we can move on.
19 |
20 | However, Cloud Firestore, the Realtime Database, Security Rules and Cloud Functions are an entirely different story.
21 |
22 | These modules are multi-purpose tools that can be used in all sorts of creative ways. We'll go much deeper into these Firebase features. We'll cover common use cases and potential pitfalls. And we'll try to inspire you with advanced architectures that will make your apps both performant and easier to write.
23 |
24 | | Module | Intensity | Reasoning |
25 | | :--- | :--- | :--- |
26 | | Console | 🌶 | A quick walk-through |
27 | | Authentication | 🌶 | Auth is the easiest Firebase feature to implement. |
28 | | Firestore | 🌶🌶🌶🌶🌶 | Firestore is the meat of Firebase's offering. |
29 | | Realtime DB | 🌶🌶🌶🌶 | The Realtime DB \(RTDB\) has some "gotchas" |
30 | | Functions | 🌶🌶🌶🌶🌶 | Functions is the back end of your app. It's tricky to develop on, but crazy powerful |
31 | | Storage | 🌶🌶 | Small API with some complexity |
32 | | Messaging | 🌶🌶 | The Firebase SDK hides most complexity |
33 | | Hosting | 🌶🌶 | Static file hosting has some detail, but it's mostly just static files. |
34 |
35 | ## Module Structure
36 |
37 | Each module will start of with an introduction. Introductions answer questions like "why do you need Firebase Authentication?" or "how does Cloud Functions work with Firestore?"
38 |
39 | Next, we'll walk through how the feature is used in a live application. This is a public-facing web app whose code you can inspect and interact with yourself. You can also pull down the code and deploy it to your own Firebase project for a deeper dive into its features.
40 |
41 | Once we've seen the Firebase service in action, we'll spin up our own Firebase project and implement a feature step by step.
42 |
43 | Finally, we'll summarize what we've learned, provide you with some notes--kind of a cheatsheet for the feature--and refer you to additional learning resources and next steps.
44 |
45 | ## Example Module
46 |
47 | Let's use Firebase Authentication as an example.
48 |
49 | First, we'll explain why Firebase Authentication is critical to your application. Why you need it, and how your app will be better because you took the time to implement it.
50 |
51 | Next, we'll show how Firebase Authentication works in our production app.
52 |
53 | Then we'll break out our code editors and implement a basic authentication. We won't go any deeper than we need to, but you'll have coded a working implementation that you can take with you.
54 |
55 | And finally we'll wrap up with a summary of how we've implemented Firebase Authentication, downloadable notes with descriptions of the functions that you should know, and suggestions for next steps in implementing Firebase Authentication in a more sophisticated way.
56 |
57 |
--------------------------------------------------------------------------------
/introduction/prerequisites.md:
--------------------------------------------------------------------------------
1 | # Prerequisites
2 |
3 | There are always prerequisites.
4 |
5 | ## JavaScript all the way down
6 |
7 | We'll be doing the bulk of our work in JavaScript. Firebase supports JavaScript for the web, Java for Android and whatever language iOS uses these days. It also has quite a bit of support for C++, Go and Python.
8 |
9 | We focus entirely on JavaScript. We only write JavaScript. We're web guys, and this is a web course, so we won't get distracted with any non-JavaScript languages.
10 |
11 | ## HTML & CSS
12 |
13 | Unfortunately for us all, the web browser is still an under-developed platform. It needs some sugar to make it digestible, and by sugar we're referring to frameworks.
14 |
15 | We're huge fans of native web components and hope that they bring an end to the JavaScript framework wars; however, we live in a world with Internet Explorer 11 and old Firefox browsers, so first-class web component support is still a few years away for most of us.
16 |
17 | Therefore we're using frameworks instead of developing in native web components. We'll stick to the two most popular and universal frameworks, Angular 2+ and React. Angular 2+ has massive adoption, and so does React. Additionally, React has spawned an entire ecosystem of spinoff frameworks such as Preact and Inferno which use JSX for rendering. If you're comfortable with JSX, you'll have no trouble following our React code.
18 |
19 | ## Firebase is vanilla
20 |
21 | The bright side is that after agonizing over framework decisions and just how we plan to render our browser pages, the Firebase SDK is entirely vanilla.
22 |
23 | And by vanilla we mean vanilla JavaScript. It's just JavaScript. You can copy/paste our code samples into Vue.js or Stenciljs or jQuery for that matter, and they will just work.
24 |
25 | The Firebase SDKs also aim for parity between Node.js and the browser. Don't get us wrong... the underlying code is quite different in Node.js and the browser environment; however, the Firebase SDK provides a very similar _**external**_ API in both environments, so your life just got much simpler. The Firebase calls that you make in the browser will look nearly identical to the calls that you'll make in Node.js.
26 |
27 | ## And speaking of Node.js...
28 |
29 | Cloud Functions, Google's functions-as-a-service or FaaS platform, uses Node.js. It also uses the command line.
30 |
31 | If you're still not comfortable with the command line, don't worry. We'll take it slowly. However! Node.js is executed on a server, not in a browser. So we'll be executing Node.js locally in our test environment before shipping it off to Cloud Functions to be run in Cloud Functions' functions-as-a-service environment.
32 |
33 | Also, some interactions with Firebase services require the _Firebase Tools_ah command-line interface or CLI. Firebase Tools is not particularly complicated... but it does use the command line.
34 |
35 | Every developer needs to get comfortable with the command line at some point. Today is a golden opportunity!
36 |
37 |
--------------------------------------------------------------------------------
/introduction/why-firebase.md:
--------------------------------------------------------------------------------
1 | # Why Firebase?
2 |
3 | Firebase is an application platform for web, Android and iOS.
4 |
5 | We know web, not Android or iOS, and we're teaching what we know; therefore, this course will be entirely focused on Firebase for web.
6 |
7 | So why should you use Firebase as your web app platform?
8 |
9 | ## Everything you need, integrated
10 |
11 | You want to use Firebase because it gives you a huge suite of services that you don't have to write.
12 |
13 | You could duplicate Firebase's services yourself, but why spend the time and money? And good luck coming in under Firebase's price point. It's not like Firebase is some extravagantly expensive service. The billing structure is entirely reasonable and one of the least expensive options... especially when you consider developer time saved.
14 |
15 | And all of Firebase's services are fully integrated. They talk to each other out of the box and use cohesive APIs. So you won't waste time architecting. You won't waste time integrating micro-services. You'll cough up a few pennies for Google's compute and storage resources, and you'll spend your valuable time writing your own application logic.
16 |
17 | In short, Firebase saves you time. We've seen greater-than 50% reductions in developer workload for even simple projects. Your codebase stays smaller. Your bugs stay fewer. And you can ship more features with the same team.
18 |
19 | And by saving you time, Firebase saves you money. Lots of money.
20 |
21 | ## Production-worthy infrastructure
22 |
23 | Startups need to write minimum-viable products. They need to prototype. They don't need to focus on scaling in the early days.
24 |
25 | Firebase lets you bootstrap your initial prototype on Google-scale infrastructure. This is a massive selling point.
26 |
27 | Consider the typical early-product lifecycle.
28 |
29 | You build a prototype. Customers like it, so you expand it to a minimum-viable product and sell it to the marketplace.
30 |
31 | The marketplace likes it, so now you have to manage a growing user-base AND ship new features.
32 |
33 | A typical startup architecture would include servers and databases, all of which you'd need to provision and scale to keep up. This leaves your team strapped for time, because they're still building new features.
34 |
35 | Firebase architecture abstracts all of that away. Your code is "serverless", meaning that you don't manage servers yourself. You write code and Firebase puts it on Google's servers and scales it up and down as needed.
36 |
37 | You can service millions of customers on the same architecture and infrastructure that you used for your prototype.
38 |
39 |
--------------------------------------------------------------------------------
/introduction/write-your-first-query.md:
--------------------------------------------------------------------------------
1 | # Write your first query
2 |
3 | We'll be using Firestore. Just follow the instructions below.
4 |
5 | ### Instructions
6 |
7 | 1. Open up [the Firestore docs](https://firebase.google.com/docs/firestore/query-data/get-data) in a new browser tab.
8 | 2. Scan the docs, especially the "Get a document" section.
9 | 3. Open another tab and go to Glitch.com.
10 | 4. Create a Glitch.com account and click around a bit to get comfortable.
11 | 5. Visit the Glitch project for this challenge, [coordinated-freighter](https://glitch.com/edit/#!/coordinated-freighter)
12 | 6. Look over the code in `index.html` and read the comments.
13 | 7. Try to query the `star-wars-people` collection inside the `getPeople()` function
14 |
15 | ## Check out your results
16 |
17 | 1. Click the "Show" button on your glitch to pop open a preview of your page.
18 | 2. [Open Chrome's DevTools](https://developer.chrome.com/devtools).
19 | 3. Navigate to the [Console](https://developers.google.com/web/tools/chrome-devtools/console/?utm_source=dcc&utm_medium=redirect&utm_campaign=2016q3) tab in DevTools to view your JavaScript output
20 |
21 | ### If you get stuck...
22 |
23 | 1. Reference [the Firestore docs](https://firebase.google.com/docs/firestore/query-data/get-data) as necessary
24 | 2. Check out the solution in `complete.html` and watch the solution video!
25 |
26 |
--------------------------------------------------------------------------------
/notes.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/how-to-firebase/full-stack-firebase/6f96681d45c1c4892423f9a16cbf0d75cbb9826a/notes.zip
--------------------------------------------------------------------------------
/notes/authentication-notes.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/how-to-firebase/full-stack-firebase/6f96681d45c1c4892423f9a16cbf0d75cbb9826a/notes/authentication-notes.pdf
--------------------------------------------------------------------------------
/notes/cloud-functions-notes.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/how-to-firebase/full-stack-firebase/6f96681d45c1c4892423f9a16cbf0d75cbb9826a/notes/cloud-functions-notes.pdf
--------------------------------------------------------------------------------
/notes/firestore-notes.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/how-to-firebase/full-stack-firebase/6f96681d45c1c4892423f9a16cbf0d75cbb9826a/notes/firestore-notes.pdf
--------------------------------------------------------------------------------
/notes/full-stack-firebase-notes-combined.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/how-to-firebase/full-stack-firebase/6f96681d45c1c4892423f9a16cbf0d75cbb9826a/notes/full-stack-firebase-notes-combined.pdf
--------------------------------------------------------------------------------
/notes/hosting-notes.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/how-to-firebase/full-stack-firebase/6f96681d45c1c4892423f9a16cbf0d75cbb9826a/notes/hosting-notes.pdf
--------------------------------------------------------------------------------
/notes/messaging-notes.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/how-to-firebase/full-stack-firebase/6f96681d45c1c4892423f9a16cbf0d75cbb9826a/notes/messaging-notes.pdf
--------------------------------------------------------------------------------
/notes/rtdb-notes.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/how-to-firebase/full-stack-firebase/6f96681d45c1c4892423f9a16cbf0d75cbb9826a/notes/rtdb-notes.pdf
--------------------------------------------------------------------------------
/notes/storage-notes.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/how-to-firebase/full-stack-firebase/6f96681d45c1c4892423f9a16cbf0d75cbb9826a/notes/storage-notes.pdf
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {
3 | "gitbook-cli": "^2.3.2"
4 | },
5 | "scripts": {
6 | "start": "gitbook serve",
7 | "install": "gitbook install",
8 | "build": "gitbook build",
9 | "build:debug": "gitbook build ./ --log=debug --debug",
10 | "versions": "gitbook ls-remote"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/realtime-database/challenge.md:
--------------------------------------------------------------------------------
1 | ---
2 | description: Realtime Database Challenge
3 | ---
4 |
5 | # Challenge
6 |
7 | ## Realtime Database
8 |
9 | ## Find the repo
10 |
11 | We'll be working on a branch of our [firelist-react](https://github.com/how-to-firebase/firelist-react) repo named [challenge-rtdb](https://github.com/how-to-firebase/firelist-react/tree/challenge-rtdb).
12 |
13 | ## Localhost installation
14 |
15 | Pull [the repo](https://github.com/how-to-firebase/firelist-react) directly from GitHub...
16 |
17 | ```text
18 | git clone https://github.com/how-to-firebase/firelist-react.git
19 | cd firelist-react
20 | git checkout challenge-rtdb
21 | ```
22 |
23 | ## Edit environment files
24 |
25 | Update the following files with your own project details:
26 |
27 | * `/.firebaserc`
28 | * `/public/environments/environment.dev.js`
29 | * `/public/environments/environment.js`
30 |
31 | ## Start the app
32 |
33 | Once you're on the branch, make sure to run `yarn` or `npm install` to get your Node.js dependencies.
34 |
35 | Then run `yarn start` or `npm run start` to spin up the development server.
36 |
37 | ```text
38 | yarn
39 | yarn start
40 | ```
41 |
42 | ## Complete the challenge
43 |
44 | Search the codebase for `Challenge Realtime DB` to find all of the challenges.
45 |
46 | Read the comments and complete the steps in those files.
47 |
48 | * `database.rules.json`
49 | * `src/database/set-user-tokens.js`
50 |
51 |
--------------------------------------------------------------------------------
/realtime-database/introduction.md:
--------------------------------------------------------------------------------
1 | # Introduction
2 |
3 | The Firebase Realtime Database \(aka "the RTDB"\) is the original database that shot Firebase onto the scene in 2012.
4 |
5 | The RTDB was one of the first "serverless" datastores on the market, competing directly with Parse and eventually with RethinkDB's Horizon project.
6 |
7 | The original innovation was to enable web browsers to connect directly to the database with a realtime web socket connection. Browsers have made HTTP calls out to API services for years, but now, instead of making manual API calls, your browser could subscribe to the database directly and receive live updates.
8 |
9 | ## JSON Datastore
10 |
11 | The RTDB is neither a relational database nor a document/collection datastore like Cloud Firestore.
12 |
13 | The RTDB is a single JSON object with up to 32 levels of depth, and you can subscribe to any node of that JSON object, whether it already exists or has yet to be made.
14 |
15 | This sort of JSON datastore makes the RTDB entirely unstructured. You can define whatever data structures you prefer in your browser and then save those data structures directly to the RTDB without modification and without telling the RTDB what the data will look like.
16 |
17 | Unstructured data can make development lightning fast... if you know what you're doing.
18 |
19 | If you're naive in how you structure your data, then you're in for very unpleasant surprises.
20 |
21 | ## Strengths
22 |
23 | The Realtime Database is ideal for realtime interactions. You could write your own web sockets server, but why? Web sockets are wicked hard to get working smoothly, and Firebase has already done the work for you.
24 |
25 | The RTDB is great for small, fast transactions. Think of the ideal RTDB use case as streaming data. You stream data to the RTDB and it streams that data out to all connected clients in a single, realtime stream.
26 |
27 | In fact, the entire Realtime Database SDK is evented. It treats data as event streams, not as fixed queries.
28 |
29 | ## Weaknesses
30 |
31 | RTDB devotees such as ourselves spent the years of 2012 through 2017 learning to model all sorts of creative data structures in pure JSON. It hasn't always been easy.
32 |
33 | We learned to host entire production applications on the RTDB long before Firestore came along to give us a more structured data model. We can model almost anything in JSON...but we don't have to do that anymore, so we'll completely avoid the RTDB's weaknesses by using Firestore for all of those use cases.
34 |
35 | ## Why is the Realtime Database so limited?
36 |
37 | The RTDB was designed for lightning fast updates. That primary design constraint prevented the Firebase team from developing sophisticated query capabilities.
38 |
39 | You can execute a single order-by filter and a single limit filter on each RTDB data stream. So you can order a list of movies by release date and request a live stream of the 10 most recent movies, but you can't also filter that stream to include only action movies. You already used your one order-by filter on the release date. Tough luck!
40 |
41 | Of course, you **can** create a new collection of movieTypes, each of which has movies ordered by release date... so your movieTypes could include action, drama and comedy, in which case you could then query the action movies list and order by release date.
42 |
43 | That achieves the same goal, but it adds a bunch of complexity to how you write your data, because now each movie has to be duplicated from the primary movies list to the appropriate movieTypes list. And what if you also want to filter by MPAA ratings? Get prepared to duplicate your data once again.
44 |
45 | ## How do we use the Realtime Database?
46 |
47 | We use the RTDB for streaming short-lived, constantly-changing data.
48 |
49 | We use it for tracking logged-in users.
50 |
51 | We use it for live progress notifications for long-running Cloud Functions.
52 |
53 | We use it for Cloud Functions job queues.
54 |
55 | And that's about it.
56 |
57 | There are plenty of other applications where the RTDB still outperforms Cloud Firestore, and we still have plenty of apps in production that use the RTDB exclusively; however, our new projects store >90% of their data in Cloud Firestore.
58 |
59 | ## Realtime Database Cost
60 |
61 | The RTDB is billed based on the gigabytes of data stored and the gigabytes transferred. This makes it ideal for smaller datasets with massive transaction counts. The RTDB doesn't care how many reads and writes you make. It cares about the volume of data travelling over the network.
62 |
63 | Don't store large volumes of data in the RTDB. That's not what it's built for, and you'll pay $5/GB every month. That's nothing if you're streaming bytes of short-lived data. Use Cloud Firestore for everything else.
64 |
65 |
--------------------------------------------------------------------------------
/realtime-database/notes.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/how-to-firebase/full-stack-firebase/6f96681d45c1c4892423f9a16cbf0d75cbb9826a/realtime-database/notes.pdf
--------------------------------------------------------------------------------
/realtime-database/walkthrough.md:
--------------------------------------------------------------------------------
1 | # Walkthrough
2 |
3 | ## Open the app
4 |
5 | Open the app at [https://glitch.com/~truth-spleen](https://glitch.com/~truth-spleen).
6 |
7 | ## Open DevTools
8 |
9 | Right-click `inspect element` and select the `Debugger` tab. Then click `command + P` to search for and open two files:
10 |
11 | * `src/components/chat-form.js`,
12 | * and `src/components/chat-wrapper.js`.
13 |
14 | 
15 |
16 | 
17 |
18 | ## Video
19 |
20 | {% embed data="{\"url\":\"https://youtu.be/OZsAHXAbPP8\",\"type\":\"video\",\"title\":\"Walkthrough: Realtime Database\",\"description\":\"Full-Stack Firebase:\\n\\nhttps://www.fullstackfirebase.com/realtime-database/walkthrough\",\"icon\":{\"type\":\"icon\",\"url\":\"https://www.youtube.com/yts/img/favicon\_144-vfliLAfaB.png\",\"width\":144,\"height\":144,\"aspectRatio\":1},\"thumbnail\":{\"type\":\"thumbnail\",\"url\":\"https://i.ytimg.com/vi/OZsAHXAbPP8/maxresdefault.jpg\",\"width\":1280,\"height\":720,\"aspectRatio\":0.5625},\"embed\":{\"type\":\"player\",\"url\":\"https://www.youtube.com/embed/OZsAHXAbPP8?rel=0&showinfo=0\",\"html\":\"\",\"aspectRatio\":1.7778}}" %}
21 |
22 |
--------------------------------------------------------------------------------
/scripts/FullStackFirebase/01.01 - full-stack-firebase (chris).txt:
--------------------------------------------------------------------------------
1 | Welcome to Full-Stack Firebase.
2 |
3 | My name is Chris Esplin.
4 |
5 | I'm a JavaScript engineer, and I love Front-End web development.
6 |
7 | I started using Firebase in 2013 when I quit my full-time job to strike out on my own.
8 |
9 | I was newly independent from the corporate environment...
10 |
11 | ...and since I didn't have any managers or co-workers...
12 |
13 | ...I got to pick my own development tools.
14 |
15 | A lot has changed, but my two constants have been JavaScript and Firebase.
16 |
17 | Yes, I've had great experiences developing outside of the Firebase ecosystem...
18 |
19 | ...but, given a choice, I always come back to Firebase.
20 |
21 | The goal of this course is for you to ship your first Firebase app to production.
22 |
23 | We'll be doing code challenges where you practice what you've learned.
24 |
25 | These challenges will use Firebase within a live, working web application.
26 |
27 | We'll be hands-on and super interactive.
28 |
29 | But you'll need to know JavaScript!
30 |
31 | If you're weak on JavaScript... this may not be the course for you.
32 |
33 | On the plus side, you don't need to know anything about Firebase to get started.
34 |
35 | Just be patient and move slowly through the material.
36 |
37 | And if you're already adept with Firebase...
38 |
39 | ...you'll want to skip around for the highlights.
40 |
41 | I'm working on this course with my good friend and fellow Google Developer Expert, Juarez Filho.
42 |
43 | Juarez and I have spent a lot of time teaching Firebase together...
44 |
45 | ...but we've never embarked on a project quite like this one.
46 |
47 | Juarez is an expert in using Firebase with Angular.
48 |
49 | I'm more experienced with other JavaScript frameworks, so I'll focus on React.
50 |
51 | Juarez is working on an Angular version of this course...
52 |
53 | ...and we'll publish that course when it's ready.
54 |
55 | But for now, we'll stick to vanilla JavaScript in a thin React shell.
56 |
57 | So let's establish some expectations.
58 |
59 | The Firebase SDK is all vanilla JavaScript...
60 |
61 | ...so if you can integrate with React...
62 |
63 | ...you can integrate with any modern framework.
64 |
65 | Second, you'll need a Firebase account.
66 |
67 | You'll probably even want to sign up for a paid account.
68 |
69 | Firebase's free Spark plan is very generous.
70 |
71 | However, there are some uses of Firebase Functions that require upgrading to a paid Blaze plan.
72 |
73 | Fortunately, these features are not required for the course.
74 |
75 | Now let's cover what this course is NOT.
76 |
77 | This course is not framework agnostic.
78 |
79 | You will see framework-specific code.
80 |
81 | This course is also not exhaustive documentation.
82 |
83 | Firebase has excellent docs, so please use the docs along with the course.
84 |
85 | We can't re-shoot videos every time the Firebase SDK gets updated.
86 |
87 | That would be insane.
88 |
89 | And one last note.
90 |
91 | Please leave us a course rating.
92 |
93 | Your feedback is super valuable.
94 |
95 | We read your comments, especially the nice ones...
96 |
97 | Anyway, now you know what to expect from Full-Stack Firebase.
98 |
99 | And we are just getting started!
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
--------------------------------------------------------------------------------
/scripts/FullStackFirebase/01.01 - full-stack-firebase.txt:
--------------------------------------------------------------------------------
1 | Welcome to Full-Stack Firebase.
2 |
3 | My name is Chris Esplin.
4 |
5 | I'm a JavaScript engineer, and I love Front-End web development.
6 |
7 | I started using Firebase in 2013 when I quit my full-time job to strike out on my own.
8 |
9 | I was newly independent from the corporate environment...
10 |
11 | ...and since I didn't have any managers or co-workers...
12 |
13 | ...I got to pick my own development tools.
14 |
15 | A lot has changed, but my two constants have been JavaScript and Firebase.
16 |
17 | Yes, I've had great experiences developing outside of the Firebase ecosystem...
18 |
19 | ...but, given a choice, I always come back to Firebase.
20 |
21 | The goal of this course is for you to roll your first Firebase app to production.
22 |
23 | We'll be doing code challenges where you practice what you've learned.
24 |
25 | These challenges will use Firebase within a live, working web application.
26 |
27 | We'll be hands-on and super interactive.
28 |
29 | But you'll need to know JavaScript!
30 |
31 | If you're weak on JavaScript... this may not be the course for you.
32 |
33 | On the plus side, you don't need to know anything about Firebase to get started.
34 |
35 | Just be patient and move slowly through the material.
36 |
37 | And if you're already adept with Firebase...
38 |
39 | ...you'll want to skip around for the highlights.
40 |
41 | I'm working on this course with my good friend and fellow Google Developer Expert, Juarez Filho.
42 |
43 | Juarez and I have spent a lot of time teaching Firebase together...
44 |
45 | ...but we've never embarked on a project quite like this one.
46 |
47 | Juarez is an expert in using Firebase with Angular.
48 |
49 | I'm more experienced with other JavaScript frameworks, so I'll focus on React.
50 |
51 | Now let's establish some expectations.
52 |
53 | First, we'll cover integration for Angular and React.
54 |
55 | The Firebase SDK is all vanilla JavaScript...
56 |
57 | ...so if you can integrate with Angular and React...
58 |
59 | ...you can integrate with any modern framework.
60 |
61 | Second, you'll need a Firebase account.
62 |
63 | You'll probably even want to sign up for a paid account.
64 |
65 | Firebase's free Spark plan is very generous.
66 |
67 | However, there are some uses of Firebase Functions that require upgrading to a paid Blaze plan.
68 |
69 | Fortunately, these features are not required for the course.
70 |
71 | Now let's cover what this course is NOT.
72 |
73 | This course is not framework agnostic.
74 |
75 | You will see framework-specific code.
76 |
77 | This course is also not exhaustive documentation.
78 |
79 | Firebase has excellent docs, so please use the docs along with the course.
80 |
81 | We can't re-shoot videos every time the Firebase SDK gets updated.
82 |
83 | That would be insane.
84 |
85 | And one last note.
86 |
87 | Please leave us a course rating.
88 |
89 | Your feedback is super valuable.
90 |
91 | We read your comments, especially the nice ones...
92 |
93 | Anyway, now you know what to expect from Full-Stack Firebase.
94 |
95 | And we are just getting started!
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
--------------------------------------------------------------------------------
/scripts/FullStackFirebase/01.02 - why-firebase.txt:
--------------------------------------------------------------------------------
1 | What is Firebase, and why should you learn it?
2 |
3 | The answer requires some explanation.
4 |
5 | Firebase is an application platform for web, Android and iOS.
6 |
7 | Juarez and I know web, not Android or iOS, and we're teaching what we know;
8 |
9 | therefore, this course will be entirely focused on Firebase for web.
10 |
11 | So why should you use Firebase as your web app platform?
12 |
13 | You want to use Firebase because it gives you a suite of services that you don't have to write.
14 |
15 | You could duplicate Firebase's services yourself, but why spend the time and money?
16 |
17 | And good luck coming in under Firebase's price point.
18 |
19 | Firebase is not expensive, especially when you consider the time you save.
20 |
21 | And all of Firebase's services are fully integrated.
22 |
23 | They talk to each other out of the box and use cohesive APIs.
24 |
25 | So you won't waste time architecting.
26 |
27 | You won't waste time integrating micro-services.
28 |
29 | You'll cough up a few pennies for Google's compute and storage resources...
30 |
31 | ...and you'll spend your valuable time writing your own application logic.
32 |
33 | We've seen greater-than 50% reductions in developer workload for even simple projects.
34 |
35 | Your codebase stays smaller.
36 |
37 | Your bugs stay fewer.
38 |
39 | And you can ship more features with the same team.
40 |
41 | And by saving you time, Firebase saves you money.
42 |
43 | Startups need to write minimum-viable products.
44 |
45 | They need to prototype.
46 |
47 | They don't need to focus on scaling in their early days.
48 |
49 | Firebase lets you bootstrap your initial prototype on Google-scale infrastructure.
50 |
51 | This is a massive selling point.
52 |
53 | Imagine this scenario for a successful new product.
54 |
55 | You build a prototype.
56 |
57 | Your testers like it, so you develop and ship a minimum-viable product.
58 |
59 | The marketplace likes it, so now you have to manage a growing user base AND ship new features.
60 |
61 | A typical startup architecture would include servers and databases...
62 |
63 | ...all of which you'd need to provision and scale to keep up.
64 |
65 | This leaves your team strapped for time, because they're still building new features.
66 |
67 | Firebase architecture abstracts all of that away.
68 |
69 | Your code is "serverless", meaning that you don't manage servers yourself.
70 |
71 | You write code and the Firebase team puts it on their servers and scales it up and down as needed.
72 |
73 | So you can service millions of customers on the same system that you used for your prototype.
74 |
75 | And that's just our first sales pitch.
76 |
77 | Stay tuned to learn even more reasons why Firebase is fantastic.
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/scripts/FullStackFirebase/01.03 - what-is-serverless.txt:
--------------------------------------------------------------------------------
1 | Firebase enables your team to use a "serverless" architecture.
2 |
3 | Serverless is a horribly misleading term, because it definitely involves servers.
4 |
5 | Lots of servers.
6 |
7 | To understand serverless, let's start with the original application architecture: the monolith.
8 |
9 | A monolithic web application is a single application that serves web pages.
10 |
11 | Monoliths are often the easiest way to write an application...
12 |
13 | ...especially in the early days of a product;
14 |
15 | however, they can be difficult to scale.
16 |
17 | So as an application grows, companies often migrate to a microservices architecture.
18 |
19 | Microservices use HTTP calls to connect tens or hundreds of tiny apps together.
20 |
21 | So instead of a single monolith that handles authentication, payments and sending email...
22 |
23 | ...a microservices architecture has one app for authentication, another for payments...
24 |
25 | ...and another for filling your inbox with marketing email.
26 |
27 | Microservices allow us to scale up just the parts of our application that need it.
28 |
29 | So a single, tiny server may handle authentication, while ten servers send email.
30 |
31 | But you still have to manage infrastructure.
32 |
33 | You still have to spin up ten email servers...
34 |
35 | ...and you still need to make sure that those email servers stay in sync as customer data changes.
36 |
37 | It's manageable, but is there a better way???
38 |
39 | Possibly!
40 |
41 | It's called "serverless".
42 |
43 | There are still plenty of servers, but you're not managing them any longer!
44 |
45 | Google, Amazon or Microsoft now get to manage the servers, and you merely manage your own code.
46 |
47 | Serverless saves you, the developer, significant time and resources.
48 |
49 | You deploy code to your service provider, and the service provider runs it.
50 |
51 | Most serverless web apps use a combination of technologies.
52 |
53 | These include single-page web applications, or SPAs...
54 |
55 | ...static file servers to serve up the SPA...
56 |
57 | ...a publicly-available database to save your app's data...
58 |
59 | ...and finally, a functions-as-a-service provider to run secure functions on a server.
60 |
61 | We'll cover all of these items in more depth as the course continues.
62 |
63 | Just know that we can use serverless to architect an app...
64 |
65 | ...that scales from prototype to massive success without us lifting a finger.
66 |
67 | So now we've introduced Firebase and we understand why we need it.
68 |
69 | Which means that we're now ready dive deeper into serverless.
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
--------------------------------------------------------------------------------
/scripts/FullStackFirebase/01.04 - write-your-first-query-challenge.txt:
--------------------------------------------------------------------------------
1 | By now you should have a vague idea of what Firebase is.
2 |
3 | It's an app platform!
4 |
5 | It rolls together a bunch of very useful technologies into a cohesive, easy-to-use whole.
6 |
7 | The core of these technologies is Firestore, the document/collection database of the FUTURE!
8 |
9 | At least... of our future... for the next few minutes.
10 |
11 | It's time for your first Full-Stack Firebase challenge!
12 |
13 | You're going to write your first Firestore query.
14 |
15 | It's going to be glorious!
16 |
17 | And it's going to be self-directed!
18 |
19 | So hang on tight... 'cause we're plunging into the deep end.
20 |
21 | You'll need a few resources to get started.
22 |
23 | These resource are available in the links for this video.
24 |
25 | You'll be reading some Firebase docs.
26 |
27 | And you'll make friends with Glitch.com...
28 |
29 | ...which is an awesome new tool for programming in a web browser.
30 |
31 | So don't be nervous.
32 |
33 | There are plenty of hints to get you going.
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/scripts/FullStackFirebase/02.02 - create-a-project.txt:
--------------------------------------------------------------------------------
1 | Creating a Firebase project is easy.
2 |
3 | Navigate to 'firebase dot google dot com' and click the Sign In...
4 |
5 | ...or Go To Console links at the top-right
6 |
7 | I see a list of my existing Firebase projects, but you'll need to add a project to get started.
8 |
9 | Click Add Project and create a project name.
10 |
11 | Project names do not need to be unique, but project IDs must be unique.
12 |
13 | If you pick a previously-used project name...
14 |
15 | ...your project ID will need extra characters on the end.
16 |
17 | We'd rather not have strange characters in our project IDs, so we try to have unique project names.
18 |
19 | Now pick a region that is close to you or to your users, then click Create Project!
20 |
21 | Now click around your brand-new project's console to get familiar.
22 |
23 | Stick to the Develop tab in the left bar, and continue on when you're ready to learn more.
24 |
25 |
26 |
--------------------------------------------------------------------------------
/scripts/FullStackFirebase/02.03 - add-some-data.txt:
--------------------------------------------------------------------------------
1 | There are two database under the Firebase brand, the Realtime Database and Cloud Firestore.
2 |
3 | We'll be sticking to Cloud Firestore for the most part, so let's get familiar with it's dashboard.
4 |
5 | Navigate to 'firebase dot google dot com', sign in to your Console, and select or create a project.
6 |
7 | Now open the Database page under the Develop section on the left bar.
8 |
9 | Select Cloud Firestore.
10 |
11 | Cloud Firestore is a document/collection database.
12 |
13 | It's best to keep collection names simple and descriptive.
14 |
15 | You can also use high-level collections to group your data.
16 |
17 | In this case, let's add a collection called "admin".
18 |
19 | We'll use this collection to store administrative documents that only we can access.
20 |
21 | Let's create our first document within "admin" and call it "salaries".
22 |
23 | Note that we could use an auto-generated document ID, but this isn't an arbitrary list.
24 |
25 | For now we're using a custom document ID to organize our data.
26 |
27 | Because this is merely organizational structure, select NULL under field type and create it.
28 |
29 | We now have an empty document named "salaries".
30 |
31 | It's useless. There's nothing here.
32 |
33 | So let's add another collection under Salaries and call it "employees"
34 |
35 | We don't have any employees yet, so we'll generate an automatic document ID.
36 |
37 | Now let's fill in some employee salary data.
38 |
39 | Notice all of the different data types that you can store, particularly the Array and Object types.
40 |
41 | Being able to save Arrays and Objects is huge.
42 |
43 | It provides maximum flexibility.
44 |
45 | Also, since each document lives on its own, you don't need consistent field names.
46 |
47 | One of our employees can have an isAdmin flag and another can have a roles array.
48 |
49 | Documents don't have to follow any sort of structure... they're extremely flexible.
50 |
51 | This is, like so many trade-offs, a blessing if you use it correctly or an awful curse.
52 |
53 | So let's cover a few hints for modeling Firestore data.
54 |
55 | First, we recommend defining data structures early using this Firestore dashboard.
56 |
57 | Go ahead and create fake data just to make sure that it works within the Firestore model.
58 |
59 | Second, just because we nested data deep in sub-collections for this demo...
60 |
61 | ...does not mean that you need to nest your own data.
62 |
63 | In fact, we recommend not nesting data unless it's truly necessary.
64 |
65 | We sometimes create high-level collections like this example for simplicity in our security rules.
66 |
67 | But otherwise, we tend not to nest data.
68 |
69 | We use lots of sibling collections and we use lots of array and object data types.
70 |
71 | This is because you can query based on a document's fields.
72 |
73 | You cannot query on a document's sub-collections.
74 |
75 | Think of sub-collections as loose affiliations.
76 |
77 | They can be powerful...
78 |
79 | ...but they're usually more trouble than they're worth.
80 |
81 |
82 |
83 |
84 |
85 |
86 |
--------------------------------------------------------------------------------
/scripts/FullStackFirebase/02.04 - browser-configuration.txt:
--------------------------------------------------------------------------------
1 | Firebase is famous for its client libraries.
2 |
3 | There are lots of database, authentication and file storage services out there...
4 |
5 | ...but Firebase is unique because you connect to its services directly from a browser or mobile app
6 |
7 | This connection is made possible by client libraries.
8 |
9 | A client library lives on your web page and maintains connections to your Firebase project.
10 |
11 | When you want to authenticate, you use the Firebase Authentication client library.
12 |
13 | When you want to save or query some data to Firestore, you have the Cloud Firestore client library.
14 |
15 | We're going to wire up a simple web page to our Firebase project.
16 |
17 | First off, let's create a fresh web project on Glitch.com.
18 |
19 | We'll be working in 'index dot html'.
20 |
21 | You'll always initialize Firebase in your 'index dot html'.
22 |
23 | Now, open a new tab to your Firebase Console via 'console dot firebase dot google dot com'
24 |
25 | Click over to your Project Overview and click "Add Firebase to your web app"
26 |
27 | Click "Copy" to grab the initialization script tags and paste them into your 'index dot html'.
28 |
29 | You can paste them in the HEAD tag or at the bottom of the BODY tag.
30 |
31 | Now let's prove to ourselves that we have a live connection to Firebase.
32 |
33 | We'll do this with anonymous authentication.
34 |
35 | So click back to your Firebase Console and select the Authentication page.
36 |
37 | Click through to the 'sign-in method' tab and enable Anonymous auth. Make sure to click SAVE.
38 |
39 | Now add 'Glitch dot me' to your authorized domains list.
40 |
41 | Note that it's Glitch dot "M" "E", not Glitch.com.
42 |
43 | That's because Glitch serves its web previews on 'Glitch dot me'.
44 |
45 | Now return to your Glitch and edit 'script dot js'.
46 |
47 | The initialization scripts that we pasted in earlier have added 'firebase' to the window object.
48 |
49 | Let's use 'window dot firebase dot auth' to get our auth client library.
50 |
51 | Then we'll create an onAuthStateChanged listener to console log our currentUser.
52 |
53 | And finally we'll call 'auth dot signInAnonymously' to authenticate.
54 |
55 | Click your Glitch's Show button to preview the page.
56 |
57 | Open up DevTools to see the logged out currentUser and to troubleshoot any errors.
58 |
59 | The most common error is that you either forgot to save when you enabled anonymous auth...
60 |
61 | ...or you didn't add 'Glitch dot me' to the authorized domains list.
62 |
63 | Review the Firebase docs if you're still having trouble.
64 |
65 | And one more note.
66 |
67 | You don't have to import the entire Firebase SDK with all of its client libraries.
68 |
69 | 'Firebase dot js' is just over 100 kilobytes right now.
70 |
71 | You can import 'firebase dash app dot js' and 'firebase dash auth dot js' instead.
72 |
73 | 'firebase app' is required for Firebase initialization.
74 |
75 | 'firebase auth' is required to use the authentication client library.
76 |
77 | These two files are about 55 kilobytes.
78 |
79 | You can import the other client libraries as needed;
80 |
81 | however, importing all of the libraries results in a larger file size than 'firebase dot js'
82 |
83 | So use this technique wisely.
84 |
85 | Now there are a few more Firebase initialization tricks that you can learn from the docs.
86 |
87 | I don't want to spoil your fun, so head on over to the docs for a quick read.
88 |
89 | We stick to the basics here.
90 |
91 | But don't let us hold you back.
92 |
93 | The Firebase docs are a treasure trove.
94 |
95 | So make sure to use them.
96 |
97 |
98 |
99 | https://firebase.google.com/docs/web/setup
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
--------------------------------------------------------------------------------
/scripts/FullStackFirebase/02.05 - node-configuration.txt:
--------------------------------------------------------------------------------
1 | Firebase wouldn't be complete without a server SDK or "software development kit"
2 |
3 | We're web developers, and we're most comfortable with JavaScript, so we use the Node SDK.
4 |
5 | Let's connect Node to our Firebase Project using the Firebase Admin SDK for Node.
6 |
7 | To get started, we'll create a fresh Node app on Glitch.com.
8 |
9 | Navigate to your Node project's 'package dot json' file and click Add Package.
10 |
11 | Search for "firebase dash admin" and add it.
12 |
13 | Now open a new tab to your Firebase Console and click the gears button...
14 |
15 | ...then click Project settings.
16 |
17 | Click the "service accounts" tab and make sure you're on the Firebase Admin SDK card.
18 |
19 | The Firebase Admin SDK is how we'll connect Node to our Firebase project.
20 |
21 | But first, we need to create a new private key.
22 |
23 | So go ahead and generate a new private key.
24 |
25 | It will download to your local downloads directory.
26 |
27 | Open your new key in the text editor of your choice and copy the contents to your clipboard.
28 |
29 | Keep this file safe, since it grants admin access to your Firebase project.
30 |
31 | Now go back to your Glitch.
32 |
33 | Create a new file under 'dot data slash service dash account dot json'.
34 |
35 | Glitch keeps files under 'dot data' private, so you won't leak your service account onto the web.
36 |
37 | Now return to your Firebase Console and make sure that you're still in the "service account" view.
38 |
39 | Click the "Copy" button to copy the Node.js connection details to your clipboard.
40 |
41 | Now return to your Glitch and replace the contents of 'server dot js' with the copied text.
42 |
43 | This will put your project in an error state.
44 |
45 | The path to your service account file is wrong.
46 |
47 | So fix the path to the service account and the error should resolve
48 |
49 | We now have a connected admin SDK.
50 |
51 | Just for funzies, let's query an empty endpoint from the Realtime Database to prove our connection.
52 |
53 | Call 'admin dot database' to get the Realtime Database library.
54 |
55 | Then chain on 'dot ref' with any string you like.
56 |
57 | And finally, chain 'dot once value' and 'dot then' to capture the data snapshot.
58 |
59 | Log out 'snapshot dot key'.
60 |
61 | It should match the same string that you used for your ref.
62 |
63 | Click the "Logs" button on your Glitch to see your project's logs and confirm.
64 |
65 | And you're configured!
66 |
67 | You've given the Admin SDK full access to your project.
68 |
69 | You can read or write anything you like using any of the Firebase features.
70 |
71 | As always, see the Firebase Docs for all of the glorious detail on the Firebase Admin SDK.
72 |
73 |
74 |
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/scripts/FullStackFirebase/02.06 - firebase-tools.txt:
--------------------------------------------------------------------------------
1 | You've used the Firebase Console.
2 |
3 | You've connected with a browser.
4 |
5 | You've connected with Node.js.
6 |
7 | Now it is time to complete your training and connect with the Firebase Tools CLI.
8 |
9 | CLI stands for command-line interface.
10 |
11 | There are some tasks that are just easier to complete via the terminal.
12 |
13 | We use the Firebase Tools CLI to configure new projects.
14 |
15 | We also use it to deploy Firebase Hosting and Cloud Functions.
16 |
17 | Let's stick to our pattern and create a new Node Project on Glitch.com.
18 |
19 | Open your project's Advanced Options and click Open Console
20 |
21 | The Glitch console or terminal--we'll use the terms interchangeably--runs Ubuntu Linux
22 |
23 | It has NPM installed, so we'll run 'npm install dash dash save dash dev firebase dash admin'
24 |
25 | The console throws some warnings, but it will install Firebase Tools locally.
26 |
27 | Once the install is complete, type 'firebase dash dash version' to check your installed version.
28 |
29 | Now type just "firebase" to see all of your options
30 |
31 | You'll see a long list of "commands" that you can execute.
32 |
33 | We'll learn the most common commands and you can return to this list to learn the rest as needed.
34 |
35 | Let's start out with firebase login.
36 |
37 | Type "firebase login dash dash no dash localhost" into your console.
38 |
39 | Your console will read out a link that you'll need to follow to complete the login process.
40 |
41 | Copy/paste the resulting authorization code into your console to complete login.
42 |
43 | Now type "firebase list" to list your active projects.
44 |
45 | If you don't have any Firebase projects listed, you'll want to create a project in your web Console.
46 |
47 | Once you have results from running "firebase list", you're ready to initialize your project.
48 |
49 | Run "firebase init" to initialize your directory to use Firebase.
50 |
51 | Use the spacebar and your up and down arrows to select all of the little check boxes
52 |
53 | We'll go ahead and use all of the Firebase features.
54 |
55 | It doesn't cost us anything.
56 |
57 | Confirm your selections and pick your project, again with the arrow keys...
58 |
59 | Then accept all of the defaults except for one.
60 |
61 | You want to type Y for "yes" when asked if you want to configure a single-page app.
62 |
63 | Glitch doesn't automatically sync the console and the editor quite yet...
64 |
65 | ...so you'll need to use the 'refresh' command to refresh your Glitch with the new files.
66 |
67 | You should now have an initialized project and be able to view your files in the Glitch editor.
68 |
69 | All that Firebase Tools did was create a bunch of configuration files.
70 |
71 | Go ahead and click around a bit through the new files to see what's been configured.
72 |
73 | We'll cover more Firebase Tools functionality as we continue through the course.
74 |
75 | For now just remember that you can always type "firebase" to read out the commands.
76 |
77 | Also, "firebase login" will authenticate a new machine and "firebase init" creates these files.
78 |
79 | And all of this means that congratulations are in order!
80 |
81 | You've completed the installation steps and have a fully-operational Firebase project!
82 |
83 | Some of this may have seemed a bit magical.
84 |
85 | Some of this may not yet make sense.
86 |
87 | But stick with it!
88 |
89 | We're building a fresh, new skill set, and that doesn't happen overnight.
90 |
91 | Hang in there.
92 |
93 | Stay patient.
94 |
95 | And you'll be a seeing awesome results before you know it!
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
--------------------------------------------------------------------------------
/scripts/FullStackFirebase/03.01 - introduction - authentication.txt:
--------------------------------------------------------------------------------
1 | You need Firebase Authentication for two reasons:
2 |
3 | Number one, Firebase Security Rules rely on Firebase Authentication
4 |
5 | And number two, Firebase Authentication is ridiculously easy to use
6 |
7 | So why does Firebase need a security system?
8 |
9 | In a traditional database you provide your own security using your API server.
10 |
11 | Since Firebase is the API server, it needs a way to control read and write access to your data.
12 |
13 | When client apps authenticate with Firebase, they receive a JSON Web Token or JWT.
14 |
15 | JWTs identify users to Firebase's security rules system.
16 |
17 | We'll cover this more later.
18 |
19 | Just remember that Firebase Authentication enables users to interact with the Firebase platform.
20 |
21 | So let's talk ease of use.
22 |
23 | Have you ever implemented your own auth system?
24 |
25 | Yes? Then you know how challenging it can be.
26 |
27 | If not... take my word for it and use an off-the-shelf system.
28 |
29 | Firebase Authentication supports a variety of ways to log into your apps.
30 |
31 | These authentication methods include:
32 |
33 | Email and password, Phone SMS, Log in with Google...
34 |
35 | ..and also Log in with Facebook, Twitter, and Github
36 |
37 | You can even roll your own custom authentication or integrate with a third-party auth system.
38 |
39 | So let's do a quick overview of these auth methods.
40 |
41 | First off is email/password auth, which is exactly as it sounds.
42 |
43 | You register an email address and a password with Firebase and it keeps track of your user account.
44 |
45 | There's nothing more to it.
46 |
47 | Next up, SMS auth!
48 |
49 | Google acquired Twitter Digits in early 2017 and rolled their phone authentication into Firebase.
50 |
51 | This means that with minimum fuss you can implement a full SMS-based phone auth flow.
52 |
53 | This is particularly great for mobile web apps.
54 |
55 | Many users prefer phone authentication, especially outside of the United States.
56 |
57 | And next we have OAuth.
58 |
59 | OAuth is a standard way to authenticate through a third-party.
60 |
61 | You know those buttons around the web that say "Log in with Facebook" or "Log in with Twitter"?
62 |
63 | That's OAuth.
64 |
65 | Firebase supports OAuth with Google, Facebook, Twitter and GitHub.
66 |
67 | OAuth is the fastest auth method, because it relies on accounts that your users already have.
68 |
69 | Most everyone has either Google, Facebook or Twitter, and developers love Github.
70 |
71 | OAuth is also the easiest auth flow to implement.
72 |
73 | And all of the OAuth providers support multi-factor authentication.
74 |
75 | Multi-factor auth uses a code generator app on your phone or a one-time code delivered via SMS.
76 |
77 | Multi-factor auth is much, much more secure than single-factor email/password auth.
78 |
79 | You should opt-in to use multi-factor whenever possible.
80 |
81 | There are no excuses.
82 |
83 | Do not get hacked.
84 |
85 | Use multi-factor auth!
86 |
87 | Ok.
88 |
89 | End rant.
90 |
91 | Finally, Firebase Authentication supports custom auth tokens.
92 |
93 | This is only relevant if you're trying to integrate with an existing auth system.
94 |
95 | Does your company use SAML or LDAP?
96 |
97 | Awesome. That's going to work just fine.
98 |
99 | Your existing auth servers can mint Firebase JWTs to give users access to their Firebase services.
100 |
101 | In conclusion, Firebase Auth is one of the simplest and highest work-to-value services around.
102 |
103 | It requires minimal dev time and provides an integrated security system for all Firebase apps.
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
--------------------------------------------------------------------------------
/scripts/FullStackFirebase/03.02 - walkthrough - authenticationi.txt:
--------------------------------------------------------------------------------
1 | Let's walk through Firebase Authentication in the wild.
2 |
3 | We'll be touring an app that I built in late 2017 to help my wife share images on the web.
4 |
5 | She had some unique sharing needs and existing services weren't cutting it...
6 |
7 | ...so I spent a few weeks writing her an image sharing app using Firebase services.
8 |
9 | This app is accessible at fogo, that's spelled F-O-G-O, 'dot how to firebase dot com'
10 |
11 | We'll open up DevTools and set two breakpoints in 'auth dot service dot js'.
12 |
13 | The first is on Line 13 on the 'firebase auth dot onAuthStateChanged' function
14 |
15 | The second breakpoint is on line 84 to capture 'firebase auth dot signInWithRedirect'
16 |
17 | Note that I'm using some fancy JavaScript services to wrap these calls...
18 |
19 | ...you do not have to get as fancy as I did with your own implementations.
20 |
21 | Auth should be easy.
22 |
23 | Now let's click log in with Google to watch the auth flow.
24 |
25 | We hit our breakpoint in signInWithRedirect.
26 |
27 | Line 84 is pulling a provider from the providersMap.
28 |
29 | If I scroll up we can get a quick view of the map.
30 |
31 | The line of interest is line 8
32 |
33 | I've called 'new firebase dot auth dot GoogleAuthProvider' to create the provider.
34 |
35 | Scrolling back down...
36 |
37 | Line 84 grabs that provider and line 85 passes it to 'firebase dot auth dot signInWithRedirect'
38 |
39 | Let's play through the breakpoint and log into a Google account.
40 |
41 | Firebase handles all of the redirects for us...
42 |
43 | ...meaning that none of this requires custom code...
44 |
45 | ...it just works.
46 |
47 | After the login, Firebase redirects us back to the page we just left.
48 |
49 | And we hit our other breakpoint on line 13.
50 |
51 | Again, I got a bit fancy here, so we'll need to step through 'auth dot onAuthStateChanged'
52 |
53 | You don't have to write wrapper functions like these... you can just write callbacks.
54 |
55 | I've set another breakpoint inside the callback to make things easier.
56 |
57 | If I hover over the currentUser you can see that there's a bunch of data here.
58 |
59 | This currentUser data is our JWT.
60 |
61 | We can scroll down a bit to see the displayName and email.
62 |
63 | A little farther down and we can see the providerData which includes a uid and more account details.
64 |
65 | So let's release the breakpoint and let the login complete.
66 |
67 | This function, onAuthStateChanged, is the core of Firebase Authentication.
68 |
69 | You can log in and log out with any auth method, and the onAuthStateChanged callback will fire
70 |
71 | So your application-specific logic only needs to listen to onAuthStateChanged!
72 |
73 | Let's sign out to see onAuthStateChanged in action.
74 |
75 | Fogo is as bit unique, so we'll have to play through the breakpoint once...
76 |
77 | ...but finally we hit our breakpoint again...
78 |
79 | ...and if we hover over currentUser, you'll see that it's null.
80 |
81 | Let's release the breakpoint to complete the sign out.
82 |
83 | Fogo's app-specific logic now has a null currentUser, so it logs us out.
84 |
85 | ... and that's it!
86 |
87 | You can log in with different OAuth providers, an email and password or even a mobile phone.
88 |
89 | Firebase Authentication is quick and easy to implement...
90 |
91 | ...and it provides the backbone for all of Firebase's security.
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
--------------------------------------------------------------------------------
/scripts/FullStackFirebase/03.04 - prompt - authenticationi.txt:
--------------------------------------------------------------------------------
1 | Are you ready for a quick win!
2 |
3 | Auth is super easy to set up.
4 |
5 | We've done most of the work in our app configuration by just enabling Google authentication.
6 |
7 | We'll be working in two files to set up authentication:
8 |
9 | - `src slash components slash authenticate dot js` and
10 |
11 | - `src slash layout dot js`
12 |
13 | You can also search the codebase for `CHALLENGE Authentication` to find the challenges.
14 |
15 | As we've shown with our Git introduction, jumping between branches is quick and easy.
16 |
17 | If you visit those two files while on `master`, you'll see that they're complete.
18 |
19 | But we want to write those ourselves, so run `git checkout challenge dash authentication`
20 |
21 | Now navigate to `src slash layout dot js` while on the `challenge dash authentication` branch.
22 |
23 | You'll see a prompt with some instructions.
24 |
25 | Follow those instructions as best you can and you should be able to get past the loading spinner.
26 |
27 | Yeah... there's a loading spinner that doesn't like that there's no `currentUser` in the app.
28 |
29 | Then hop over to `src slash components slash authenticate dot js` to complete the second challenge.
30 |
31 | These two challenges should take between five and thirty minutes.
32 |
33 | The code itself is dead simple, but you may need to read the instructions...
34 |
35 | ...and the docs...
36 |
37 | ...a few times before you see the pattern to follow.
38 |
39 | Don't guess wildly. Read the docs until you see the solution, then take a stab at it.
40 |
41 | And that's all you'll need for authentication!
42 |
43 | Watch the Authentication Solution video for a full explanation of the code.
44 |
45 | And you can always check out master to take a peek at the finished code.
46 |
47 | The easiest way to switch to master is to type `git stash` to stash your local changes...
48 |
49 | ...then `git checkout master` to see the finished code.
50 |
51 | Once you've figure out the code a bit better, type `git checkout challenge dash authentication`...
52 |
53 | ...then `git stash pop` to restore the changes that you just stashed.
54 |
55 | `git stash` is super useful.
56 |
57 | Search it up on Bing to become a `git stash` master!
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/scripts/FullStackFirebase/03.05 - solution - authentication.txt:
--------------------------------------------------------------------------------
1 | We have two tasks to complete to implement Firebase Authentication.
2 |
3 | First, we need to fill in our signIn function in `authenticate dot js`.
4 |
5 | Second, we'll need an onAuthStateChanged listener in `layout dot js`.
6 |
7 | So let's start with `authenticate dot js`...
8 |
9 | If we follow the prompt and visit the Google sign-in docs...
10 |
11 | ... we see that the code to create a Google Auth Provider is copy/paste.
12 |
13 | So we'll copy/paste that bit of code and we have a provider!
14 |
15 | Next we call `firebase dot auth` and then `signInWithPopup` with the provider as the argument.
16 |
17 | And that's it for our signIn function.
18 |
19 | On to 'layout dot js'...
20 |
21 | Let's review the docs for onAuthStateChanged.
22 |
23 | onAuthStateChanged takes a callback, and it usually only needs to be called once per application.
24 |
25 | The beauty of onAuthStateChanged is that it handles auth changes for all authentication methods.
26 |
27 | So we'll start by calling `this dot firebase dot auth` to get the Auth client library.
28 |
29 | Then we pass a callback function into `onAuthStateChanged`.
30 |
31 | The callback receives the `currentUser` object, which is either null or a JWT.
32 |
33 | We'll do our application-specific logic in the callback, setting the current user...
34 |
35 | ...and calling `setUserTokens` if a logged-in currentUser exists.
36 |
37 | Our function is complete, but we should talk about the architecture behind `setUserTokens`.
38 |
39 | See, we want access to our users' JWTs in our database, but we don't want to trust our users.
40 |
41 | We should assume that our users are all malicious hackers...
42 |
43 | ...and we don't want to let hackers write their own user details to the DB.
44 |
45 | So we're letting users write their 'user tokens' to the Realtime Database.
46 |
47 | Later on we'll write a Cloud Function to verify users' tokens and write the verified data to the DB.
48 |
49 | We can grant users read-only access to their user data...
50 |
51 | ...and we know that the data is real, because we got it from the Cloud Function's verified token.
52 |
53 | This is a common pattern with Cloud Functions.
54 |
55 | Give users write access to one part of the database...
56 |
57 | ...and intercept those writes with a Cloud Function.
58 |
59 | The Cloud Function handles whatever verification we need and writes to a read-only part of the DB.
60 |
61 | But don't worry about that too much now!
62 |
63 | We'll cover it in detail in the section on Cloud Functions.
64 |
65 | In the meantime, let's click around our newly-functional app.
66 |
67 | Notice how we can log out?
68 |
69 | Well check out `src slash components slash toolbar dot js`
70 |
71 | There's a `signOut` function at the bottom of the file that calls `firebase dot auth` and `signOut`.
72 |
73 | Kind of simple isn't it?
74 |
75 | Yeah... we didn't think it was worth writing a challenge prompt.
76 |
77 | Anyway... click around and get comfortable with the functioning app.
78 |
79 | And if you'd like an extra challenge, try implementing Facebook auth or email/password auth.
80 |
81 | You'll want to start by reading up on the docs surrounding different auth providers.
82 |
83 | It's a little more complicated than Google Auth, so don't get too sidetracked...
84 |
85 | ...however, it might be worth spending ten to twenty minutes just messing around.
86 |
87 |
88 |
--------------------------------------------------------------------------------
/scripts/FullStackFirebase/04.02 - walkthrough - firestore.txt:
--------------------------------------------------------------------------------
1 | It's time to see Firestore in action.
2 |
3 | But we have one quick note before diving in.
4 |
5 | We're about to visit "Fogo dot how to Firebase dot com".
6 |
7 | Fogo is a live production application.
8 |
9 | So the code you're about to see is complicated, because the app is complicated.
10 |
11 | Fogo took weeks to build, and we don't expect you to understand the code.
12 |
13 | We just want you to see a real-life, production-grade Firestore implementation.
14 |
15 | The internet is full of simple little demo apps that make everything look so easy.
16 |
17 | But real-life apps are all complicated...
18 |
19 | ...and we can't be scared off just because we don't understand something.
20 |
21 | So let's get started with Fogo.
22 |
23 | Fogo is an image-management application, and as such, it needs to handle thousands of images.
24 |
25 | We would never attempt to display thousands of images in a browser, so we'll paginate our results.
26 |
27 | We've implemented a form of infinite-scroll pagination...
28 |
29 | ...where a new page is requested whenever the bottom of the list becomes visible to the user.
30 |
31 | Firestore collections can be easily paginated with a cursor.
32 |
33 | The word cursor is just fancy database speak for the last record a query has returned.
34 |
35 | So let's load Fogo's main images list and step through these queries.
36 |
37 | We'll start with a breakpoint in "images dot query dot js".
38 |
39 | imagesQuery handles the initial and all subsequent page loads.
40 |
41 | If there's no data in the store, it loads the first page of records.
42 |
43 | If there is data in the store, it looks at the last result, which we've called the cursor...
44 |
45 | ...and it modifies the query to start after that cursor and grab the next page.
46 |
47 | Line 5 shows that our collection is named "uploads".
48 |
49 | Line 6 is a simple "where" clause to limit the query to our current environment.
50 |
51 | We've tagged all image records with an environment flag.
52 |
53 | This way we can support multiple instances of the app on a single Firebase project.
54 |
55 | And then, on line 7, we order by a created timestamp in descending order.
56 |
57 | This way we get the newest records first.
58 |
59 | Then line 8 sets a limit on the number of records to return using the "dot limit" function
60 |
61 | Line 9 is where the pagination is done.
62 |
63 | If we call imagesQuery with a cursor, we'll use startAfter to paginate off of "cursor dot created"
64 |
65 | If there is no cursor, then we skip the pagination and the query is just the limitedCollection
66 |
67 | Line 11 awaits "query dot get", and lines 12 through 21 process the results
68 |
69 | Our first time through this query returns our 25 most-recent results.
70 |
71 | Let's scroll down to trigger another page load...
72 |
73 | and this time there's a cursor, so we've started after that cursor and we get the next page.
74 |
75 | imagesQuery is great for paginating existing records, but it can't handle new records
76 |
77 | For that, we'll set a breakpoint in "images dot observer dot js".
78 |
79 | imagesObserver uses onSnapshot to listen to new records as they're added.
80 |
81 | You'll notice that lines 6 through 11 look familiar from the last query...
82 |
83 | but line 10 is new, because it's going to use a "where" clause to only query new records
84 |
85 | We pass in a lastCreated timestamp to indicate the most recent record that the app has seen...
86 |
87 | ...and imagesObserver now only returns records with a more recent timestamp than lastCreated.
88 |
89 | Line 14 uses onSnapshot to start listening to the collection.
90 |
91 | Each snapshot returned by onSnapshot will have all of the newer records.
92 |
93 | So if we add one new image, the snapshot will include that image...
94 |
95 | ...and if we add another image, onSnapshot will fire a second time, but this time with both images.
96 |
97 | Lines 15 through 23 are some application-specific logic to process the incoming records...
98 |
99 | ...and also to remove any duplicates from earlier onSnapshot events.
100 |
101 | So let's add an image to watch onSnapshot fire.
102 |
103 | onSnapshot fires with an empty snapshot when it's first called, because there are no new records.
104 |
105 | But then the new records hit Firestore, and onSnapshot fires again...
106 |
107 | ...this time with a single record in snapshot dot docs.
108 |
109 | And that's it!
110 |
111 | We have infinite-scroll pagination as well as a listener that handles realtime updates.
112 |
113 | And we achieved this epic feat with under 50 lines of code.
114 |
115 | We've written this behavior before with the Realtime Database...
116 |
117 | ...and it was well over 100 lines of code, and pagination was much more confusing.
118 |
119 | These queries may seem a bit complicated, because they are.
120 |
121 | So don't worry if you didn't understand this code.
122 |
123 | We'll clear it all up, step by step, in the upcoming videos.
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
--------------------------------------------------------------------------------
/scripts/FullStackFirebase/05.01 - introduction - rtdb.txt:
--------------------------------------------------------------------------------
1 | The Realtime Database, or RTDB, is the original product that shot Firebase onto the scene in 2012.
2 |
3 | The RTDB was one of the first "serverless" datastores on the market.
4 |
5 | It has two primary innovations.
6 |
7 | First is that it's built to be realtime and super fast.
8 |
9 | You aren't allowed to write slow queries for the Realtime Database.
10 |
11 | Second, the RTDB has client libraries.
12 |
13 | Client libraries enable your browser application to connect directly to the database.
14 |
15 | Client libraries are part of what makes an application "serverless", because they skip the server.
16 |
17 | So what is the Realtime Database, and what does it do?
18 |
19 | The RTDB is neither a relational database nor a document/collection datastore like Cloud Firestore.
20 |
21 | The RTDB is a single JSON object with up to 32 levels of depth.
22 |
23 | You can query any node of that JSON object, whether it already exists or has yet to be made.
24 |
25 | This sort of JSON datastore makes the RTDB entirely unstructured.
26 |
27 | You first define whatever data structures you prefer in your application code.
28 |
29 | Then you save that data directly to the RTDB without modification...
30 |
31 | ...and without telling the RTDB what the data will look like.
32 |
33 | Unstructured data can make development lightning fast... if you know what you're doing.
34 |
35 | If you're naive in how you structure your data, then you're in for very unpleasant surprises.
36 |
37 | So let's talk about the Realtime Database's strengths.
38 |
39 | The Realtime Database is ideal for realtime interactions.
40 |
41 | Think of the ideal RTDB use case as streaming data.
42 |
43 | You stream data to the RTDB and it streams that data out to all connected clients.
44 |
45 | Imagine a chat feature.
46 |
47 | Building chat with the Realtime Database is a piece of cake.
48 |
49 | Every user in the chat room is subscribed to the data feed.
50 |
51 | As users add messages to the data feed, they're automatically sent to the connected clients.
52 |
53 | The Realtime Database excels at these sorts of fast, small data changes.
54 |
55 | But most app features don't need fast, small data.
56 |
57 | And that's where the Realtime Database has its weaknesses.
58 |
59 | RTDB devotees such as ourselves spent the years of 2012 through 2017 getting very creative.
60 |
61 | We learned to model all sorts of crazy data structures in pure JSON.
62 |
63 | It was not easy.
64 |
65 | But we were devoted to building our entire apps on the Realtime Database...
66 |
67 | ...so we made it work, and we shipped highly performant apps to our users.
68 |
69 | We can model almost anything in JSON... but we don't have to do that anymore...
70 |
71 | ...because now we have Firestore.
72 |
73 | We'll completely avoid the RTDB's weaknesses by using Firestore for all of those use cases.
74 |
75 | So why is the Realtime Database limited?
76 |
77 | The RTDB was designed for lightning fast updates.
78 |
79 | That primary design constraint prevented the Firebase team from developing sophisticated queries.
80 |
81 | You can execute a single order-by filter and a single limit filter on each RTDB data stream.
82 |
83 | So you can order a list of movies by release date and query a stream of the 10 most recent movies...
84 |
85 | ...but you can't also filter that stream to include only action movies.
86 |
87 | You already used your one order-by filter on the release date.
88 |
89 | So tough luck!
90 |
91 | There are workarounds, but they're not necessary anymore...
92 |
93 | ...so we're not going to cover them!
94 |
95 | We'll only cover the use cases where Firebase is preferred to Firestore.
96 |
97 | We use the RTDB for streaming short-lived, constantly-changing data.
98 |
99 | We use it for tracking logged-in users.
100 |
101 | We use it for live dashboards.
102 |
103 | We use it for progress bars.
104 |
105 | And that's about it.
106 |
107 | Over 90% of our new app features now use Firestore.
108 |
109 | But the Realtime Database is still useful, and it isn't going away.
110 |
111 | So as long as we have it, we'll embrace its strengths and sidestep its weaknesses.
112 |
113 |
114 |
115 |
116 |
--------------------------------------------------------------------------------
/scripts/FullStackFirebase/05.02 - walkthrough - rtdb.txt:
--------------------------------------------------------------------------------
1 | The Firebase Realtime Database is perfect for chat features.
2 |
3 | We're going walk through the Firebase-specific code in a small chat demo.
4 |
5 | This demo is hosted on Glitch.com, so you can inspect the code and remix it yourself.
6 |
7 | But this walk through does not need to be interactive, so sit back and relax.
8 |
9 | This app is a single, basic feature.
10 |
11 | You can log in, send messages and read the last 50 messages.
12 |
13 | In fact, you're welcome to log into the app yourself and leave us trolly comments.
14 |
15 | Anyway, we'll open up "chat dash wrapper dot js" and set breakpoints on lines 25, 44, 47 and 55.
16 |
17 | Let's start by refreshing the page to see how the the messagesQuery gets set.
18 |
19 | messagesQuery is generated using what we call a Firebase ref.
20 |
21 | We first need to access the Realtime Database client library by calling "firebase dot database".
22 |
23 | Then we create the ref with a string representing the slash-delimited path to the node we want.
24 |
25 | We've arbitrarily picked a node with a ref name of "authenticated slash react dash chat slash room"
26 |
27 | Refs can accept any path up to 32 levels deep.
28 |
29 | You don't need to define your paths beforehand...
30 |
31 | ...Firebase will create whatever data structure it needs in order to save your data.
32 |
33 | Once we have the ref, we'll call limitToLast to limit our result set to the last 50 records.
34 |
35 | Now let's release our breakpoint and log in.
36 |
37 | Our listenToMessages function sets an "on child-added" listener on line 44
38 |
39 | The child-added event fires once for every existing record and for every new record as it's added.
40 |
41 | So the callback will now fire 50 times to load the initial query results.
42 |
43 | We can hover over the results of "snapshot dot val" to see a query result.
44 |
45 | The next three lines add the message to the app's record set.
46 |
47 | Let's remove the breakpoint and play through to see the results.
48 |
49 | Our app has loaded the last 50 messages and we can scroll through to read them.
50 |
51 | Now let's enable our breakpoint again and send another message.
52 |
53 | We'll also set breakpoints in "chat dash form dot js" on lines 22 and 31.
54 |
55 | Line 22 shows how we get the room ref to add the new message.
56 |
57 | On line 31 we use ref dot push to push a new record onto our room ref.
58 |
59 | Let's open our Firebase Console to see our data structure.
60 |
61 | Notice how the JSON attributes correspond to the ref path that we used earlier.
62 |
63 | Our data is nested under "authenticated slash react dash chat" and the room name, Default Chat Room.
64 |
65 | We'll open up the data structure for the room and then let our breakpoint play through.
66 |
67 | Back on the Firebase Console we can open up our new message to see the results.
68 |
69 | The child-added callback fires immediately with the new message.
70 |
71 | And we can see the message in our chat window.
72 |
73 | Now let's sign out.
74 |
75 | We've lost our authenticated session with Firebase, so we need to stop listening to the query.
76 |
77 | Line 55 shows how we do that.
78 |
79 | We've saved our messageHandler on line 44, so we call "messagesQuery dot off"...
80 |
81 | ...with the child-added string and the messagesHandler
82 |
83 | And now we've cleaned up our listener and logged out of of our app.
84 |
85 | See how easy that was?
86 |
87 | You're one step closer to being an expert Realtime Database user!
88 |
89 | There are a few more query filters that you can use, but it's all a variation on this theme.
90 |
91 | You create a ref, apply any filters that you need, and listen for results.
92 |
93 |
94 |
95 |
96 |
--------------------------------------------------------------------------------
/scripts/FullStackFirebase/05.03 - prompt - rtdb.txt:
--------------------------------------------------------------------------------
1 | Welcome back!
2 |
3 | If you've followed these lessons sequentially, then you recently survived Firestore security rules.
4 |
5 | So congratulations for that feat of patience and long-suffering.
6 |
7 | Thankfully, our next topic is significantly less masochistic.
8 |
9 | We'll be wiring up our demo app to use the Realtime Database, also known as the RTDB.
10 |
11 | As we've mentioned before, the RTDB has been overshadowed by Firestore, so we use it sparingly.
12 |
13 | In the demo app, we're using it to queue up jobs for Cloud Functions.
14 |
15 | The RTDB is super cheap to use for this type of application.
16 |
17 | The bandwidth required to create a job queue is minimal, so our fees will be minimal too.
18 |
19 | All we want to do is to write users' secure tokens to a sort of write-only dropbox endpoint.
20 |
21 | We've decided to call this endpoint `userWriteable slash userTokens slash uid`.
22 |
23 | We're going to write users' idTokens from Firebase Authentication...
24 |
25 | ...and we're going to piggy back on this queue to write our Firebase Messaging tokens as well.
26 |
27 | We haven't written the Firebase Messaging code yet...
28 |
29 | ...but we will have to pass secure tokens from Firebase Messaging on the client to our server...
30 |
31 | ...and since that needs to be a secure operation, we'll do it with a Cloud Function.
32 |
33 | So let's write the code.
34 |
35 | Search for `challenge realtime db` or use your file browser.
36 |
37 | Open up `src slash database slash set dash user dash tokens dot js`.
38 |
39 | You'll want to read the docs and follow the prompt.
40 |
41 | This will teach you how to write data to the Realtime Database.
42 |
43 | This app doesn't read data from the RTDB, so we won't be covering that.
44 |
45 | While writing your data, you may get errors due to misconfigured security rules.
46 |
47 | You'll need to set your RTDB security rules anyway, so open up `database dot rules dot json`.
48 |
49 | You'll see a prompt to write your first security rule for the RTDB.
50 |
51 | Go ahead and follow that prompt, and you should be able to write data up to the RTDB.
52 |
53 | The demo app is configured to write `userTokens` up to the RTDB every time a user logs in.
54 |
55 | Firebase Authentication will automatically log you in when you reload the page...
56 |
57 | ...so you can trigger write attempts by simply reloading the page.
58 |
59 | Once you've either successfully written your data or spent more than about a half hour on this...
60 |
61 | ...jump to the solutions video to check your work.
62 |
63 | There's no point in getting hung up if this challenge proves tricky.
64 |
65 | We're not spending a ton of time on the RTDB...
66 |
67 | ...and our primary objective is simply to understand what it does.
68 |
69 | If you know what it does, you'll be able to read the docs and figure the rest out.
70 |
71 | The hardest part is usually understanding how the pieces of the Firebase puzzle fit together.
72 |
73 | Actually assembling the pieces is made doable with Firebase's excellent docs.
74 |
75 |
76 |
--------------------------------------------------------------------------------
/scripts/FullStackFirebase/05.04 - solution - rtdb.txt:
--------------------------------------------------------------------------------
1 | Now that you've taken a crack at writing some RTDB code, let's review.
2 |
3 | Open up `src slash database slash set dash user dash tokens dot js`.
4 |
5 | We first create a `userTokensRef` by chaining off of `environment dot firebaseRoot`.
6 |
7 | We like to include a `firebaseRoot` variable at the bottom level of our RTDB objects.
8 |
9 | This allows us to host multiple apps on the same RTDB database without conflicting;
10 |
11 | however, this is just our preference.
12 |
13 | It's probably not even a best practice... we've just done this for years and like the pattern.
14 |
15 | So now that we have our `userTokensRef`, let's create our cleaned-up `userTokens` object.
16 |
17 | `userTokens` needs two tokens, the `idToken` and the `messagingToken`.
18 |
19 | `messagingToken` is likely missing, so we'll pass this object through `omitEmptyValues`.
20 |
21 | `omitEmptyValues` is a utility function that we like to use with the RTDB.
22 |
23 | See, the RTDB HATES undefined values.
24 |
25 | RTDB data is meant to be sparse, meaning that you don't save a key if there's no value for it.
26 |
27 | So the RTDB will throw errors at you if you attempt to save an undefined value.
28 |
29 | We use our `omitEmptyValues` utility function to clean up our RTDB objects before writing them.
30 |
31 | So pass the `userTokens` object through `omitEmptyValues`...
32 |
33 | ...and pass the result through to `userTokensRef dot set`.
34 |
35 | And this code should be complete.
36 |
37 | Now make sure your local server is running with `yarn start` and log in or reload the page.
38 |
39 | If this code runs correctly, you'll see a new object written to your Realtime DB.
40 |
41 | Now what about security rules?
42 |
43 | Firestore has security rules, and the Realtime DB has them too.
44 |
45 | So let's open up `database dot rules dot json` to secure our RTDB.
46 |
47 | The RTDB uses Firebase's legacy security rules framework.
48 |
49 | The old security rules are based off a JSON object with a `rules` attribute at its root.
50 |
51 | You'll nest attributes under `rules` to match your data shape.
52 |
53 | This is another situation where reading the docs is critical.
54 |
55 | So make sure to comb through the security rules docs before trying to ship RTDB code to production.
56 |
57 | We'll be moving quickly with some basic rules.
58 |
59 | First, we needs to create some nesting in the JSON structure to match our data shape.
60 |
61 | RTDB security rules use a dollar sign to indicate wildcard attributes...
62 |
63 | ...so we'll nest `dollar environment`, `userWriteable`, `dollar objectType`, and `dollar uid`.
64 |
65 | This can be the most perplexing part of RTDB security rules, so let's stop to review.
66 |
67 | `dollar environment` will correspond to the base node in our data structure...
68 |
69 | ...in this case it's the string 'development', but it could be 'test' or 'production'.
70 |
71 | Next, we have a hard-coded string, `userWriteable`.
72 |
73 | `userWriteable` is not a wildcard.
74 |
75 | It's a hard-coded path.
76 |
77 | Next we have `dollar objectType`.
78 |
79 | We're using an `objectType` wildcard here so that we don't have to write extra rules.
80 |
81 | The beauty here is that we're creating a sort of 'dropbox' under `userWriteable`.
82 |
83 | We're going to be writing `userTokens` right now, but in the future we could write anything.
84 |
85 | Instead of `userTokens`, we could write `outgoingSMS` or `notificationsToSend`...
86 |
87 | ...it's really arbitrary.
88 |
89 | As long as the `objectType` is nested under `userWriteable`, the rules will apply.
90 |
91 | After `dollar objectType` we have the most important node, `dollar uid`.
92 |
93 | `dollar uid` will be required under `dollar objectType`, and we'll write our security rule using it.
94 |
95 | So let's create a `dot write` rule to verify that `auth dot uid` equals `dollar uid`.
96 |
97 | The affect of this rule is that users can only write to their own nodes.
98 |
99 | They can write to any `objectType`... but they have to write with a matching uid.
100 |
101 | A lousy hacker could write a bunch of garbage data, but we'd see and delete it.
102 |
103 | And the hacker couldn't write data for other users due to the `auth dot uid` rule.
104 |
105 | Note that we're just writing a `dot write` rule.
106 |
107 | We could have written a `dot read` rule as well, but it would have been hard-coded to false.
108 |
109 | Also note that we have access to the user's JWT through the `auth` variable.
110 |
111 | So we can use `auth dot uid` and compare it to the `uid` wildcard in our `dot write` rule.
112 |
113 | So let's deploy our rules.
114 |
115 | Check your `dot firebaserc` file to make sure that you're not deploying to `firelist dash react`.
116 |
117 | Make sure that you have your own project ID under the `default` attribute.
118 |
119 | Once you're sure of that, open your terminal and run `firebase deploy dash dash only database`.
120 |
121 | You should see your security rules deploy up to your Firebase console, so check the console.
122 |
123 | If those rules match, reload your localhost app again to make sure that your data is writing.
124 |
125 | You should be able to delete your `userTokens` object manually and reset it by reloading the app.
126 |
127 | Our app-specific logic is writing our `userTokens` every time a user logs in or reloads the page.
128 |
129 | And since your `userTokens` are now flowing up to the RTDB...
130 |
131 | we're ready to write some Cloud Functions!
132 |
133 |
134 |
135 |
136 |
--------------------------------------------------------------------------------
/scripts/FullStackFirebase/06.01 - introduction - functions.txt:
--------------------------------------------------------------------------------
1 | Cloud Functions is a huge part of the Firebase ecosystem.
2 |
3 | It just came out of beta in 2018, and it's changing the way we code.
4 |
5 | Cloud Functions is the connective tissue that makes Firebase a "serverless" platform.
6 |
7 | Secure operations are unavoidable in production applications.
8 |
9 | Sure, you can make a quick demo that doesn't need to send any email or accept a Stripe payment...
10 |
11 | ...but most apps are worthless without secure, administrative operations.
12 |
13 | Functions-as-a-service, or FaaS, let's us perform secure server operations without managing a server
14 |
15 | Cloud Functions is a Functions-as-a-Service provider that's integrated into the Firebase platform.
16 |
17 | So we can ship single JavaScript functions to Cloud Functions and trigger them in a variety of ways.
18 |
19 | Cloud Functions runs on servers, but you don't get to interact with those servers.
20 |
21 | Cloud Functions has your code and will run it as Cloud Functions sees fit.
22 |
23 | It can spin up 20 servers to handle a spike in traffic...
24 |
25 | ...and it can spin them all down again without any input from you or your code.
26 |
27 | Cloud Functions is a Google Cloud Platform or GCP service...
28 |
29 | ...but it has a series of Firebase-specific events...
30 |
31 | ...so we often refer to those events as Cloud Functions for Firebase.
32 |
33 | Cloud Functions is for all of GCP, not just Firebase...
34 |
35 | ...but it's especially useful when combined with Firebase.
36 |
37 | Cloud functions can be triggered with HTTP calls, changes to the Realtime Database or Firestore...
38 |
39 | ...account creation or deletion with Firebase Authentication...
40 |
41 | ...and object changes in Firebase Storage.
42 |
43 | Cloud Functions enables you to get truly creative in how you architect your serverless apps.
44 |
45 | You can craft highly scalable job pipelines...
46 |
47 | ...implement complex messaging systems...
48 |
49 | ...or simply track and tweak your data as your users make changes to your databases.
50 |
51 | Start out with simple functions.
52 |
53 | Don't get carried away until you're comfortable with the basics.
54 |
55 | Cloud Functions is an ocean;
56 |
57 | You should wade around in the shallows before heading out to deep water.
58 |
59 | Cloud Functions has made possible entirely new application architectures.
60 |
61 | The Firebase community is still inventing best practices and discovering what's possible.
62 |
63 | We are in the early stages of a serverless revolution...
64 |
65 | ...so it's an exciting time to be a Firebase developer.
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/scripts/FullStackFirebase/06.02 - walkthrough - functions.txt:
--------------------------------------------------------------------------------
1 | Cloud Functions is not for the faint of heart.
2 |
3 | It's extremely powerful, but it can drive you crazy.
4 |
5 | Fortunately for you, we've developed great methods for developing Cloud Functions...
6 |
7 | ...and we'll teach you all of them in the coming videos.
8 |
9 | But for now, let's walk through some Cloud Functions code on Glitch.com.
10 |
11 | It's the chat app that we walked through earlier, but this time, it has Cloud Functions.
12 |
13 | We'll start on "functions slash index dot js"
14 |
15 | This file is the entry point for all Cloud Functions for Firebase.
16 |
17 | We're importing the firebase functions library as well as a local library named "stats"
18 |
19 | "stats" is the function that we're going to execute.
20 |
21 | To attach stats to Cloud Functions we call "functions dot database dot ref".
22 |
23 | "Dot ref" takes a string representing the path to which we'd like to listen...
24 |
25 | ...with curly braces around wildcard parameters, in this case "room" and "key".
26 |
27 | Then we call "dot onCreate" and pass in our stats function.
28 |
29 | Now our stats function will run any time data is created on a matching path.
30 |
31 | So let's inspect our stats function.
32 |
33 | Every event is a bit different.
34 |
35 | In this case we're listening to a Realtime Database onCreate event.
36 |
37 | onCreate functions get called with two parameters, the database snapshot and a context object.
38 |
39 | The first few lines of our stats function pull variables off of our context object and snapshot.
40 |
41 | We use those variables to defined two Realtime Database refs.
42 |
43 | Once we have our refs we can calculate our stats.
44 |
45 | We'll do those calculations with two transaction functions.
46 |
47 | We're using transactions because Cloud Functions does not guarantee execution order.
48 |
49 | If we quickly create hundreds of records, our functions will likely execute out of order.
50 |
51 | Realtime Database transactions are functions that take the existing value from the db...
52 |
53 | ...complete the necessary modifications, and return a new value.
54 |
55 | Our two transactions increment a couple of counters and track some user activity.
56 |
57 | The code here isn't important... it's just some arbitrary tracking data we chose to collect.
58 |
59 | What is important is that our Cloud Function returns a promise.
60 |
61 | Cloud Functions requires that we return a promise if we are executing asynchronous code.
62 |
63 | If you fail to return a promise your asynchronous code may fail to execute...
64 |
65 | ...and Cloud Functions will throw nasty errors to your logs.
66 |
67 | We've used "Promise dot all" to guarantee that this function will not return prematurely.
68 |
69 | Now let's see this function in action.
70 |
71 | We'll open our Glitch web preview first.
72 |
73 | Now let's open our Firebase Realtime Database console next to it.
74 |
75 | This is a simple chat app, so let's add some messages and watch the data flow through.
76 |
77 | Over on our console we can see the data flowing into the chat room.
78 |
79 | We can also see the stats records getting incremented and overwritten.
80 |
81 | Finally, if we go to our Cloud Functions logs we can track each execution.
82 |
83 | Cloud Functions is the glue that holds the Firebase platform together.
84 |
85 | You'll need Cloud Functions to take your Firebase apps to production...
86 |
87 | ...so pay close attention to the coming videos.
88 |
89 | There's a lot to learn, and it may help you level up significantly as a developer.
90 |
91 |
92 |
93 |
94 |
95 |
--------------------------------------------------------------------------------
/scripts/FullStackFirebase/07.01 - introduction - storage.txt:
--------------------------------------------------------------------------------
1 | Most production apps will eventually need to handle user-uploaded files.
2 |
3 | Uploaded files are different than the data that we store in a database, because they're big.
4 |
5 | Data fields are tiny, usually just a few bytes.
6 |
7 | Image files are massive, often many megabytes in size.
8 |
9 | Images, PDFs, Word Docs... in database land, these are known as BLOBs.
10 |
11 | A BLOB is a binary large object.
12 |
13 | It's a big chunk of data that we can't see into.
14 |
15 | We're not saving the data across multiple database fields... it's just a single BLOB.
16 |
17 | Dealing with files or BLOBs has traditionally been a massive pain in the neck.
18 |
19 | They're usually too big to get sent over the internet with a single HTTP call...
20 |
21 | ...so they have to be streamed across the wire with tens or hundreds of calls.
22 |
23 | This involves having a sophisticated client-side uploader as well as a server to receive the stream.
24 |
25 | The server has to collect chunks of streamed data, reassemble them...
26 |
27 | ...and send the result to a hosting service.
28 |
29 | Firebase Storage solves this file-upload problem once and for all.
30 |
31 | Firebase Storage enables you to stream files directly from your browser to the hosting provider.
32 |
33 | In this case, the host is a Google Cloud Storage bucket, similar to Amazon's S3 service.
34 |
35 | It's a bucket meant to host and serve files, and Firebase Storage uploads to it directly.
36 |
37 | So while Firebase Storage may not seem like a huge feature...
38 |
39 | ...it's just for uploading files right?...
40 |
41 | ...these file uploads are miserable to write on your own.
42 |
43 | Anyone who has ever written a file uploader will appreciate the glory that is Firebase Storage.
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/scripts/FullStackFirebase/07.02 - walkthrough - storage.txt:
--------------------------------------------------------------------------------
1 | The Firebase Storage client library is the smallest Firebase client library.
2 |
3 | It does one thing, and it does it easily.
4 |
5 | You pass Firebase Storage a browser File object and tell it where to upload the file.
6 |
7 | Firebase Storage starts the upload and lets you track progress, errors and completion.
8 |
9 | It's that simple.
10 |
11 | We're going to watch Firebase Storage in action on "fogo dot how to firebase dot com".
12 |
13 | So let's go to the app now and open DevTools.
14 |
15 | We'll set some breakpoints in "storage dot service dot js".
16 |
17 | Line 5 is the instantiation of the Storage client library.
18 |
19 | Line 12 creates a storage ref, which is any arbitrary file path.
20 |
21 | You can create any sort of folder structure and choose a filename at this point.
22 |
23 | Line 13 calls "ref dot put" with the File object as the argument...
24 |
25 | ...and it saves the resulting task.
26 |
27 | The task is now the source of our upload progress updates.
28 |
29 | The task is a promise, so line 17 registers a 'dot then' callback.
30 |
31 | Lines 19 through 23 register callbacks for progress, error and success events.
32 |
33 | This storage service is an RxJs wrapper that enables sequential uploading of files.
34 |
35 | Don't worry about this application-specific code...
36 |
37 | ...it will look familiar if you've used RxJS...
38 |
39 | ...but RxJs isn't part of this course, so you can ignore it!
40 |
41 | Let's start a file upload to watch how the code flows.
42 |
43 | But first we'll need breakpoints on lines 12, 21 and 23.
44 |
45 | We'll start the upload and watch the code break on line 12.
46 |
47 | This is where we define the ref with the folder value being "howtofirebase slash uploads"
48 |
49 | The "file dot name" value is the name of the file from our filesystem.
50 |
51 | Let's step through to pass the file and task out to our RxJs observer...
52 |
53 | ... and register a 'dot then' callback for when the task is completed.
54 |
55 | Now we'll let the breakpoints play through while the upload completes.
56 |
57 | We'll receive a progress event on line 21.
58 |
59 | bytesTransferred are zero and the state is 'running'
60 |
61 | After a couple more progress events we'll see that the bytesTransferred matches the file size...
62 |
63 | ...at which point our success callback, the third in the list, gets called.
64 |
65 | Let's deactivate the breakpoints and run that one more time with a bigger file.
66 |
67 | Notice the green progress bar?
68 |
69 | That progress percentage is calculated from the bytesTransferred value in the progress callback.
70 |
71 | And we're done!
72 |
73 | Just to confirm that the file uploaded, let's visit our Firebase Console's Storage page.
74 |
75 | We navigate through the howtofirebase and uploads folders to find our uploaded file.
76 |
77 | We can click on the file to see a preview and some metadata.
78 |
79 | And there's not much more to it!
80 |
81 | We'll cover implementation details in the following videos...
82 |
83 | ...but now you've seen what Firebase Storage does...
84 |
85 | ...and with a bit of instruction, you'll have no trouble implementing it yourself!
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
--------------------------------------------------------------------------------
/scripts/FullStackFirebase/07.03 - prompt - storage.txt:
--------------------------------------------------------------------------------
1 | Let's write some Firebase Storage code!
2 |
3 | But first, we need to make sure that our Cloud Functions are all deployed correctly.
4 |
5 | So checkout the `challenge dash storage` branch with `git checkout challenge dash storage`.
6 |
7 | If you have changes in your repo that are not environment files...
8 |
9 | ...then you're about to have merge conflicts.
10 |
11 | So let's remove all of those non-environment changes.
12 |
13 | Run `git status` to see your change set.
14 |
15 | If you're following along in VSCode, you can use the Git tab to do this manually.
16 |
17 | You can reset each file individually in VSCode...
18 |
19 | ...or you can do bulk checkout operations in your terminal.
20 |
21 | If you just finished with the Cloud Functions module, use `git checkout functions slash src`....
22 |
23 | ...to restore your functions source files without messing up your environment files.
24 |
25 | Once your changeset is just your environment files, go ahead and check out `challenge dash storage`,
26 |
27 | And just to be certain that your Cloud Functions are in good order...
28 |
29 | ...let's run `yarn deploy colon functions` to get a fresh Functions deploy.
30 |
31 | This may take a few seconds....
32 |
33 | ...and once it's done...
34 |
35 | ...search the codebase for `challenge storage` to find the two challenge files.
36 |
37 | We'll start with `src slash storage slash get dash upload dash observable dot js`.
38 |
39 | This is vanilla Firebase Storage code wrapped in an RxJs observable...
40 |
41 | ...much like we did in our earlier Firestore challenges.
42 |
43 | So follow the instructions and you'll soon be able to upload files from your localhost app.
44 |
45 | Next let's navigate to `src slash storage slash delete dash image dot js`.
46 |
47 | This one's even easier than the last challenge.
48 |
49 | The answer is a one-liner that will delete files from your Cloud Storage bucket.
50 |
51 | Once that's done, you'll be able to delete your uploads from the localhost app.
52 |
53 | If you get stuck or aren't done within about half an hour, just jump to the solution.
54 |
55 | But make sure to read the docs and let yourself struggle a bit.
56 |
57 | Learning how to debug these sorts of systems is critical to being a great programmer...
58 |
59 | ...and it's critical to bringing your own Firebase apps to production.
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/scripts/FullStackFirebase/07.04 - solution - storage.txt:
--------------------------------------------------------------------------------
1 | Firebase Storage is one of our favorite Firebase features.
2 |
3 | It's easy to use and very powerful.
4 |
5 | It's really not fair to all of the other storage providers out there.
6 |
7 | So let's start by serving up our localhost app with `yarn start`.
8 |
9 | Once we're up and running, let's create a note and attempt to upload an image to it.
10 |
11 | Nothing will happen... because we haven't completed the challenge code yet!
12 |
13 | So let's get started in `src slash storage slash get dash upload dash observable dot js`.
14 |
15 | We'll start out by defining our file ref with `storage dot ref`.
16 |
17 | We'll pass the `path` variable in as our base ref, then call `dot child` with `file dot name`.
18 |
19 | This lets us chain our way to a complete file path.
20 |
21 | We could have created a concatenated string and just used a single `storage dot ref` call...
22 |
23 | ...but using `dot child` can lead to cleaner reading code.
24 |
25 | Now we'll define the `uploadTask` with `ref dot put` with the `file` as the argument.
26 |
27 | The `uploadTask` enables us to register a `state underscore changed` listener...
28 |
29 | ...using `uploadTask dot on` with the first argument as `state underscore changed`.
30 |
31 | The next three arguments are all callback functions.
32 |
33 | The first will be our progress callback.
34 |
35 | We'll receive the snapshot, pass it through `getSnapshotProgress` to get a progress value...
36 |
37 | ...and we'll call `observer dot next` with the progress value.
38 |
39 | The next callback is for any errors, which we'll pass through directly with `observer dot error`.
40 |
41 | And finally, the third callback is for completion and just needs a call to `observer dot complete`.
42 |
43 | And we're done with one small exception...
44 |
45 | ...make sure to check your `public slash environments` files.
46 |
47 | If the `uploadPath` attribute in either file still refers to `firelist dash react`...
48 |
49 | ...you'll need to change that reference to your own project.
50 |
51 | You'll need files to upload to a folder that has your project name in the path.
52 |
53 | Once that's confirmed, go ahead and upload a file using your localhost app!
54 |
55 | You'll know that the upload is complete when you see a trashcan icon in the corner of the image.
56 |
57 | Go ahead and check your Firebase Console's storage page to confirm that your upload made it.
58 |
59 | And maybe check your Functions page as well to see the logs and confirm that the Function fired.
60 |
61 | Once you have the upload feature working, let's write the delete code!
62 |
63 | Navigate to `src slash storage slash delete dash image dot js` and follow the prompt.
64 |
65 | This one's a piece of cake.
66 |
67 | We'll call `storage dot ref` with the `name` variable as the argument...
68 |
69 | Then we call `dot delete` off of the result, which should delete our image.
70 |
71 | Let's test it in the demo app.
72 |
73 | Click the delete button and you'll see the image grey out.
74 |
75 | This indicates that the Cloud Function is processing the delete action.
76 |
77 | Once the Cloud Function has processed the deletion, the image will disappear from your note.
78 |
79 | Check your Storage console and Functions console to confirm that it all executed correctly.
80 |
81 | You should now be able to upload and delete files as needed.
82 |
83 | Go ahead and test with a variety of image files.
84 |
85 | This isn't the most robust system, meaning that uploading bulk images won't work great...
86 |
87 | ...we'd need to build some fancy upload queueing to accomplish that...
88 |
89 | ...but this system covers the basics and enables us to upload and delete, which is all we need.
90 |
91 |
92 |
--------------------------------------------------------------------------------
/scripts/FullStackFirebase/08.01 - introduction - messaging.txt:
--------------------------------------------------------------------------------
1 | Firebase Cloud Messaging, or FCM, lets you send notifications to Android, iOS and browser apps.
2 |
3 | You know when your web browser asks for your permission to send you notifications?
4 |
5 | And you click "allow" and start receiving a bunch of system-level popups from Chrome or Firefox?
6 |
7 | We've seen this a lot with apps like Google Calendar, Google Hangouts and Facebook Messenger.
8 |
9 | These notifications got popular on Android and iOS, so browser vendors started to support them too.
10 |
11 | Firebase Cloud Messaging is the easiest way to send these notifications.
12 |
13 | We will, of course, learn the browser implementation of FCM.
14 |
15 | The FCM libraries aren't nearly as big as those of the Realtime Database and Firestore;
16 |
17 | however, implementing FCM requires both client-side browser code and server code in Node.js.
18 |
19 | This makes FCM one of the most complicated implementations in the Firebase ecosystem.
20 |
21 | Go ahead and skip this section if you're feeling overwhelmed.
22 |
23 | You can always come back to it later.
24 |
25 | But make sure to watch it if you're confident in your Node.js and browser skills.
26 |
27 | The code itself isn't complicated...
28 |
29 | ...it just crosses back and forth between Node and the browser, which can be confusing.
30 |
31 | Although not every app needs messaging, it's growing in popularity.
32 |
33 | And if you ever need to implement messaging...
34 |
35 | Firebase Cloud Messaging is by far the easiest way to do it.
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/scripts/FullStackFirebase/08.02 - walkthrough - messaging.txt:
--------------------------------------------------------------------------------
1 | Let's walk through a basic Firebase Cloud Messaging implementation on Glitch.com.
2 |
3 | We've prepared this Glitch as a standalone example to make FCM as easy-to-understand as possible.
4 |
5 | Feel free to remix this Glitch or copy/paste code for your own implementations.
6 |
7 | FCM is one of those systems where copying and pasting code is a best practice.
8 |
9 | It's mostly boilerplate...
10 |
11 | ...and that's what open-source code is all about.
12 |
13 | You can sit back and relax... because this is just another walk through.
14 |
15 | We'll go through the FCM implementation in detail later on.
16 |
17 | Our Glitch is named 'fine ping', so we'll navigate to "fine dash ping dot glitch dot me".
18 |
19 | We'll open DevTools and find the "client dot js" source file.
20 |
21 | We'll set breakpoints on lines 35, 54, 56, 59 and 70.
22 |
23 | Let's reload the page to see line 35, where we're instantiating the messaging client library.
24 |
25 | Now let's sign in with Google to get an authenticated user.
26 |
27 | Once we've signed in, we'll click the 'request permission' button.
28 |
29 | This triggers our breakpoint on line 54
30 |
31 | A simple call to "messaging dot requestPermission" causes the browser to request our permission.
32 |
33 | We allow permission, which calls the callback on line 56.
34 |
35 | Line 56 calls "messaging dot getToken" to generate a unique token for the browser session.
36 |
37 | We receive the token on line 59 and send the token to the Realtime Database.
38 |
39 | Let's navigate to our Realtime Database console to see the data.
40 |
41 | It's all under "authenticated slash notification dash users".
42 |
43 | You can see the existing user objects with their tokens.
44 |
45 | Now back to the Glitch web page to define a message, any message.
46 |
47 | We'll click on the 'send' button to trigger line 70.
48 |
49 | Line 70 sends a POST request to our server.
50 |
51 | Notice the token and message query parameters.
52 |
53 | We'll let that play through and go check out the server code.
54 |
55 | "Server dot js" contains our POST handler.
56 |
57 | It pulls the token and message attributes from "request dot query" and sends the message.
58 |
59 | "Admin dot messaging" gets the server library and "dot send" does the sending.
60 |
61 | The message body needs token and data attributes, which will go straight to our client.
62 |
63 | Let's return to the client and trigger another message.
64 |
65 | Each message triggers the onMessage callback on line 41 of "client dot js".
66 |
67 | The onMessage callback gets triggered whenever the app is active in the browser.
68 |
69 | But what if the app is closed or running in the background?
70 |
71 | Can we still receive notifications?
72 |
73 | Of course we can!
74 |
75 | We can use a service worker to execute code while our app is in the background.
76 |
77 | In the DevTools console there's an application tab that lets us view our service worker code.
78 |
79 | We'll select the Service Workers page and click through to our service worker.
80 |
81 | Line 14 registers our 'set background message handler' callback.
82 |
83 | It's like the earlier 'on message' callback, but it only fires when the app is in the background.
84 |
85 | So let's trigger a message while the app is in the background!
86 |
87 | We'll do this by going to the Network tab in DevTools and finding our last sendMessage POST.
88 |
89 | We'll right-click on the request and copy the request as CURL.
90 |
91 | Now we'll hop into our bash command line and fire off the CURL command to recreate the POST.
92 |
93 | This example is using the Windows 10 Linux Sub-system version of BASH.
94 |
95 | If you try this copy-as-curl trick on MacOS, you don't need to use the Linux sub-system.
96 |
97 | MacOS has a bash terminal by default... so your life is that much easier.
98 |
99 | We've left the Glitch app in the front of our browser, so the regular alert triggers.
100 |
101 | Let's try that again while on a different tab.
102 |
103 | We send the CURL command again...
104 |
105 | ...and check that out!
106 |
107 | It's a system-level notification from our browser.
108 |
109 | This example sends a single message to a single user.
110 |
111 | Real-life production apps will need a lot more application-specific logic.
112 |
113 | You can use FCM to subscribe users to topic messaging lists...
114 |
115 | ...and you can use Node.js to send mass messages to those topic lists.
116 |
117 | Also, you'll need to manage user tokens in a more sophisticated way...
118 |
119 | ...because this system only saves one token per user.
120 |
121 | In real life, users log in with lots of different browsers, each of which needs its own token.
122 |
123 | And another quick note...
124 |
125 | Firebase Cloud Messaging uses the browser's Push API.
126 |
127 | The Push API is currently only supported by Chrome and Firefox...
128 |
129 | ...so don't build mission-critical functionality with these kinds of messages.
130 |
131 | Firebase Cloud Messages should be viewed as a progressive enhancement...
132 |
133 | ...meaning that users with better browsers get the enhanced experience...
134 |
135 | ...but we need to develop our app to still work well for less-privileged users.
136 |
137 | That was all very fast...
138 |
139 | ...and bouncing between client and server code is confusing.
140 |
141 | So hang in there.
142 |
143 | We'll be building a production-grade messaging framework.
144 |
145 | And you'll be able to use your framework in any app with just a bit of copy/paste.
146 |
147 |
148 |
149 |
150 |
151 |
--------------------------------------------------------------------------------
/scripts/FullStackFirebase/08.03 - prompt - messaging.txt:
--------------------------------------------------------------------------------
1 | It's time to implement our own Firebase Cloud Messaging system.
2 |
3 | It's not too difficult if we take each step carefully.
4 |
5 | So let's check out `challenge dash messaging` with `git checkout challenge dash messaging`.
6 |
7 | You'll likely need to remove your changes from prior modules, so run `git checkout src`...
8 |
9 | ...which will reset all changes within the `src` folder.
10 |
11 | Run `git status` to confirm that your current change set is merely environment files.
12 |
13 | Once that's complete, go ahead and check out `challenge dash messaging` and we'll get to work.
14 |
15 | Search the codebase for `challenge messaging` to see the seven challenge prompts.
16 |
17 | We'll follow them in order.
18 |
19 | Let's get started with `src slash messaging slash get dash token dot js`.
20 |
21 | You'll need to review the docs from each challenge prompt, but it should not be too difficult.
22 |
23 | The final challenge, number 7, doesn't require any coding...
24 |
25 | ...but read the docs and understand the code referenced in the challenge...
26 |
27 | ...as it will make your own implementations of Firebase Cloud Messaging much easier.
28 |
29 | These challenges may take an hour or two, because you will need to read a bit and experiment.
30 |
31 | Frankly, the hardest part of this entire thing is the serviceWorker.
32 |
33 | You'll want to debug your service worker by opening Dev Tools in your localhost app.
34 |
35 | Go to the 'Application' tab and click the 'Service Workers' side tab.
36 |
37 | You can review the loaded service worker code by clicking the `sw dot js` link next to source.
38 |
39 | If we make a trivial change to the service worker and reload the page...
40 |
41 | ...we need to return to the 'Application' tab and 'Service Workers' side tab to load the code.
42 |
43 | You'll likely see a `waiting to activate` message...
44 |
45 | ...because service workers don't automatically update themselves.
46 |
47 | So click the `skipWaiting` link next to the orange `status` dot to load it immediately.
48 |
49 | Now you can click through to `sw dot js` to confirm that your code has changed.
50 |
51 | Once all of the challenges are complete...
52 |
53 | ...you can trigger notifications by adding yourself as a note collaborator.
54 |
55 | But first you'll need to go to your Account page by clicking the menu button on the top-left.
56 |
57 | Once you are on your account page, click the `activate notifications` button.
58 |
59 | If nothing happens, you may have already accepted or blocked site notifications...
60 |
61 | ...in which case you'll want to click Chrome's page security button next to the URL field.
62 |
63 | Click the 'Site Settings' link at the bottom of the menu.
64 |
65 | The relevant preference is 'Notifications', which you'll want to be `ask default`.
66 |
67 | Once that's done, reload your page and try activating notifications again.
68 |
69 | Click 'Allow' to kick off a Cloud Function that sets the `messagingToken` user attribute.
70 |
71 | You can confirm that the attribute is set by going to your Firestore console and finding your user.
72 |
73 | Scroll down to check for a `messagingToken`.
74 |
75 | It should be a long string that looks like gibberish.
76 |
77 | That's the token that Firebase Cloud Messaging uses to identify your browser for messages.
78 |
79 | Note that this token requires Cloud Functions to be working...
80 |
81 | ...so you may need to debug the Functions logs.
82 |
83 | Once you have a `messagingToken`, you'll notice that the text on your Account page changes.
84 |
85 | The button should now read 'deactivate notifications'.
86 |
87 | Now you can create or edit a note and add yourself as a collaborator.
88 |
89 | Just make sure to match your email address and you should get an alert from the bottom of the page.
90 |
91 | As always, check out the challenge solution if you're getting stuck...
92 |
93 | ...and we'll see each other in the next video!
94 |
95 |
96 |
97 |
--------------------------------------------------------------------------------
/scripts/FullStackFirebase/09.01 - introduction - hosting.txt:
--------------------------------------------------------------------------------
1 | Firebase Hosting is meant to serve the static web assets that form your client application.
2 |
3 | Hosting is for JavaScript, CSS, HTML and other static assets like images.
4 |
5 | This is perfect for apps that are rendered client-side with React or Angular.
6 |
7 | It's not perfect for server-side rendered applications like those written in PHP or Ruby...
8 |
9 | ...in fact, there's no server-side code executed on Firebase Hosting.
10 |
11 | However, Hosting includes a few useful features in addition to static file hosting.
12 |
13 | Hosting lets you define URL redirects and URL rewrites.
14 |
15 | It also lets you rewrite paths to an HTTP Cloud Function.
16 |
17 | URL Redirection is the simplest to understand.
18 |
19 | When you hit a redirected URL, the server tells your client that the requested asset has moved.
20 |
21 | Your client changes the URL in the address bar to the new location and requests the asset again.
22 |
23 | URL rewrites are server-side only, meaning that your client won't change the URL in the address bar.
24 |
25 | When you rewrite a URL you tell the server to internally return a different asset...
26 |
27 | ...but you don't want the client app to know what the server did.
28 |
29 | Rewriting to a cloud function is a perfect example.
30 |
31 | You can define a URL rewrite for Firebase Hosting that redirects all requests to a Cloud Function.
32 |
33 | HTTP Cloud Functions have ugly URLs.
34 |
35 | It's just part of how Cloud Functions works.
36 |
37 | So Firebase Hosting allows you to rewrite your pretty client-facing urls...
38 |
39 | ...to internally redirect to the ugly Cloud Function HTTP endpoint.
40 |
41 | Another nicety of Firebase Hosting is that it integrates tightly with the Firebase platform.
42 |
43 | You can roll back Hosting deploys on the Firebase Console.
44 |
45 | You can also deploy directly from the Firebase Tools CLI.
46 |
47 | And finally, Firebase Hosting lets you connect a custom domain...
48 |
49 | ...and it will mint a free SSL certificate for that custom domain.
50 |
51 | Hosting will not serve your content over insecure HTTP...
52 |
53 | ...it always uses HTTPS.
54 |
55 | Firebase Hosting does not have an exhaustive feature set like Apache or NGINX...
56 |
57 | ...and that's the point.
58 |
59 | It's meant for serverless web apps and nothing else.
60 |
61 | Firebase Hosting is so well done that it has attracted its own following...
62 |
63 | ...meaning that developers are using Hosting even when they don't need the platform's databases.
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/scripts/FullStackFirebase/09.02 - walkthrough - hosting.txt:
--------------------------------------------------------------------------------
1 | Firebase Hosting is the one feature where you won't be writing any code.
2 |
3 | There's a single configuration file.
4 |
5 | There's a deploy command.
6 |
7 | And there's a Firebase Console page.
8 |
9 | That's it.
10 |
11 | So let's check out a simple Hosting implementation in a Glitch.
12 |
13 | This Glitch is named 'ripe knife', and you can follow along on Glitch.com.
14 |
15 | Let's start with "firebase dot json".
16 |
17 | This file is for Firebase configuration.
18 |
19 | We have a single node to configure hosting.
20 |
21 | The "public" folder is "public", so you'll notice that Hosting deploys only our "public" folder.
22 |
23 | Next, we've ignored some common files and folders that you'd never want deployed.
24 |
25 | Then come the rewrites.
26 |
27 | Order matters here.
28 |
29 | Our first rewrite is for 'slash hey dash guys'.
30 |
31 | It rewrites to a Cloud Function named helloWorld.
32 |
33 | If we pop over to 'functions slash index dot js', we can see that helloWorld returns some HTML.
34 |
35 | Back at 'firebase dot json'...
36 |
37 | ...we have another rewrite.
38 |
39 | If the first 'hey guys' rewrite is not applied, the second rewrite gets evaluated.
40 |
41 | This is a 'star star' rewrite, meaning that it matches all files.
42 |
43 | So all paths besides 'hey guys' will get rewritten to 'index dot html'.
44 |
45 | This is a standard rewrite for single-page apps that need to funnel urls through one entry point.
46 |
47 | An important note here is that this "star star" rewrite won't get applied for existing files.
48 |
49 | This means that if you request 'slash public slash style dot css', you'll get the css file.
50 |
51 | That's because Hosting searches the file system and tries to return static assets first.
52 |
53 | It only evaluates the rewrites after that point.
54 |
55 | Finally, we've redirected 'slash console' to the Firebase Console URL for this project.
56 |
57 | Let's see this in action on the hosted page.
58 |
59 | The bare URL returns the contents of 'index dot html'.
60 |
61 | We can add some gibberish to the end of the URL and it's rewritten back to 'index dot html'.
62 |
63 | If we request the existing css file, we can see that 'style dot css' gets returned.
64 |
65 | Our other rewrite, 'hey dash guys', returns the result of the Cloud Function.
66 |
67 | And finally, 'slash console' redirects us to our console.
68 |
69 | You've come this far, so Firebase Hosting will not be a challenge.
70 |
71 | It's just a great feature that ties together the platform and makes "serverless" easier.
72 |
73 |
74 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/scripts/FullStackFirebase/09.03 - prompt and solution - hosting.txt:
--------------------------------------------------------------------------------
1 | Firebase Hosting does not lend itself to challenges and solutions.
2 |
3 | We're going to walk through the three processes that matter and be done with it.
4 |
5 | There are exactly three things to keep track of...
6 |
7 | ...first is our production app build...
8 |
9 | ...second is our `firebase dot json` file...
10 |
11 | ...and finally we have the deploy command.
12 |
13 | The production build relies on `public slash environments slash environment dot js`...
14 |
15 | ...so double-check that you didn't leave any default data in your production environment file.
16 |
17 | Our production build is kicked off with `yarn build` or `yarn build colon windows`.
18 |
19 | You can check out `package dot json` to see the details of those two commands.
20 |
21 | They're basic Webpack commands to run our production build and nothing more.
22 |
23 | Webpack builds our app into a folder named `dist`.
24 |
25 | `dist` is the folder that we'll be sending to Firebase Hosting.
26 |
27 | Next, we need to tell Firebase Hosting how to deploy our app, so let's open `firebase dot json`.
28 |
29 | `firebase dot json` has four attributes...
30 |
31 | ...three of which tell the `firebase tools` cli where our security rules files are located...
32 |
33 | ...and another attribute...`hosting`... that describes the hosting deploy.
34 |
35 | The `hosting` attribute indicates that our `public` folder is `dist`...
36 |
37 | ...and it tells Hosting to ignore a few file patterns.
38 |
39 | These ignores are defaults from running `firebase init` at the beginning of our project.
40 |
41 | We don't include any of these files in our `dist` build...
42 |
43 | ...but we'll hang onto these ignores anyway.
44 |
45 | The `rewrites` attribute is also a default that we selected when running `firebase init`.
46 |
47 | We told the `firebase tools` cli to redirect all unrecognized routes to `index dot html`...
48 |
49 | ...and this is the rewrite rule to do that.
50 |
51 | You can do some pretty sophisticated rewrites and redirects with Firebase Hosting...
52 |
53 | ...but that's entirely application-specific and well documented in the Firebase docs...
54 |
55 | ...so we won't get distracted now.
56 |
57 | Finally, we just need to run our deploy job.
58 |
59 | Fire off `yarn deploy colon hosting` in your terminal.
60 |
61 | This is a command defined in `package dot json` so let's check out that file while we deploy.
62 |
63 | These deploy commands follow a simple pattern...
64 |
65 | ...`firebase deploy dash dash only` followed by the service name.
66 |
67 | You can install `firebase dash tools` globally and run these CLI commands directly.
68 |
69 | We wanted to package this app in a self-contained way, so we installed `firebase tools` locally.
70 |
71 | If you're using a Node executable locally...
72 |
73 | ...you have to kick it off from a `package dot json` script...
74 |
75 | ...which is why we've included so many scripts in our `package dot json`.
76 |
77 | Anyway, once our deploy is complete we'll see our 'Hosting URL' in the terminal...
78 |
79 | ...so let's visit it!
80 |
81 | A couple of notes regarding caching...
82 |
83 | ...because we're using a serviceWorker cache, which is incredibly persistent.
84 |
85 | If you find yourself debugging deploys, make sure to clear your site data manually.
86 |
87 | You can do that by navigating to DevTools' Application tab and the 'Clear storage' side tab.
88 |
89 | Clear that site data and refresh your page...
90 |
91 | ...and make sure that you have the latest serviceWorker code.
92 |
93 | And a second note...
94 |
95 | ...the `messagingToken` on our 'Account' page is the same token that we had on localhost.
96 |
97 | We need to deactivate and activate it again to receive messages from the production app.
98 |
99 | This app does not do a good job of separating between the localhost and production data.
100 |
101 | You'd typically deploy your production app to an entirely different Firebase project...
102 |
103 | ...but we've developed and deployed with a single project for simplicity.
104 |
105 | That means that we have one set of data and one set of Cloud Functions and a single deploy.
106 |
107 | This is not ideal for a production application...
108 |
109 | ...so make sure to have separate Firebase projects for each environment when you develop a real app.
110 |
111 | And that's it.
112 |
113 | Really.
114 |
115 | We made it.
116 |
117 |
118 |
119 |
120 |
121 |
--------------------------------------------------------------------------------
/scripts/FullStackFirebase/10.01 - conclusion.txt:
--------------------------------------------------------------------------------
1 | This has been a massive amount of information.
2 |
3 | We've done our best to deliver it clearly, but we're sure we came short in numerous places.
4 |
5 | The best way to ask questions is on our GitHub projects.
6 |
7 | Please, please, please let us know how we messed up.
8 |
9 | Go to `github dot com slash how dash to dash firebase` and find the appropriate repo.
10 |
11 | For example, if you have questions about `firelist react`...
12 |
13 | ...ask questions in the `firelist react` repo.
14 |
15 | File as many issues as you like.
16 |
17 | We're happy to chat and answer questions... whatever you need!
18 |
19 | Juarez and I have social channels that you can hit up as well.
20 |
21 | We're on twitter as `chrisesplin` and `juarez p a f`...
22 |
23 | ...so slide into our DMs anytime.
24 |
25 | And thank you!
26 |
27 | Thank you for persevering through such a challenging topic.
28 |
29 | This course is an attempt to give an efficient overview of Firebase for web...
30 |
31 | ...because it has to be Full-Stack Firebase.
32 |
33 | Anything less than a full-stack approach wouldn't do the platform justice.
34 |
35 | We want to de-mystify Firebase development and help startups and large companies alike.
36 |
37 | We want Firebase to be the most popular way to develop a serverless web application.
38 |
39 | Great technology is absolutely nothing without great community...
40 |
41 | ...so welcome to the Firebase community!
42 |
43 | We're a beginner-friendly group, and Juarez and I aim to be as accessible as humanly possible.
44 |
45 | So don't be shy.
46 |
47 | Let us know what you're thinking...
48 |
49 | ...and we can grow the Firebase community together and take our own skills to the next level.
50 |
51 |
--------------------------------------------------------------------------------
/scripts/FullStackFirebase/11.01 - chris esplin promo.txt:
--------------------------------------------------------------------------------
1 | Welcome to Full-Stack Firebase with me, Chris Esplin
2 |
3 | I am a front-end web developer and co-founder of calligraphy dot org
4 |
5 | I'm also a Google Developer Expert with a specialization in Firebase
6 |
7 | Calligraphy dot org and all of my projects run on the Firebase app platform and have since 2013
8 |
9 | I've taught Firebase at programming bootcamps, Firebase hackathons and on my YouTube channel
10 |
11 | Firebase is one of the best things to happen in the web ecosystem in the last five years
12 |
13 | Firebase is a full-featured application platform that enables rapid, scalable app development
14 |
15 | Full-Stack Firebase will teach you Firebase's JavaScript SDK
16 |
17 | It will also teach you the building blocks of serverless application development
18 |
19 | At the end of this course you'll have the skills to take Firebase apps from prototype to production
20 |
21 | We'll cover Firebase Authentication, Cloud Firestore, the Realtime Database...
22 |
23 | ...Cloud Functions, Firebase Storage, Firebase Cloud Messaging and Firebase Hosting
24 |
25 | We'll learn what each of these features adds to the Firebase ecosystem
26 |
27 | We'll see each of these features in action in a live web application
28 |
29 | And finally, we'll build our own application, together, using each Firebase feature
30 |
31 | Full-Stack Firebase is designed for JavaScript developers looking to get started with Firebase
32 |
33 | Students don't need any prior experience except for basic JavaScript and HTML
34 |
35 | Your time is valuable.
36 |
37 | Do not waste it learning Firebase the hard way.
38 |
39 | Take the shortest path to Firebase mastery with Full-Stack Firebase.
40 |
--------------------------------------------------------------------------------
/scripts/YouTube/0001.001 - firebase vs firestore.txt:
--------------------------------------------------------------------------------
1 | Welcome back to How To Firebase!
2 |
3 | You may have noticed that I've been missing for just about a year :)
4 |
5 | Two things happened.
6 |
7 | First, I got super busy and started a full-time job.
8 |
9 | So my free time has been cut way, way back.
10 |
11 | Second, I decided to up my video game and produce a full-blown Firebase course.
12 |
13 | I'll be teasing that new content here in the coming weeks and months.
14 |
15 | The course will be a paid experience, which means that I'm spending a lot more time on each video.
16 |
17 | But I'm still committed to open-source.
18 |
19 | Therefore, you can find my written course content on FullStackFirebase.com
20 |
21 | So hop on over to FullStackFirebase.com to follow along as I write and publish.
22 |
23 | The course is taking a lot longer than I'd hoped, and I need to keep publishing stuff to YouTube.
24 |
25 | So when I come across a topic that doesn't fit cleanly into the course...
26 |
27 | I'll cut a video and post it here!
28 |
29 | And that brings us to today's topic, Firebase vs Firestore.
30 |
31 | I know a lot of you are super happy with the Firebase Realtime Database.
32 |
33 | You're probably wondering why you'd want to mess with anything else.
34 |
35 | So here we go!
36 |
37 | Firebase's Realtime Database is a JSON datastore. It's totally unstructured, which is a blessing and a curse.
38 |
39 | What makes the Realtime Database popular is it's awesome client libraries.
40 |
41 | Client libraries let you connect from your app--be it web, Android or iOS--directly to the database.
42 |
43 | So you could save your JSON directly to the Realtime Database without transforming it at all.
44 |
45 | And you could quickly fetch your data back with realtime change detection.
46 |
47 | The Realtime Database made our lives so much easier!
48 |
49 | Firestore is built to work side-by-side with the Realtime Database.
50 |
51 | Using Firestore does not mean abandoning the Realtime Database...
52 |
53 | but you'll likely find that it's better for most tasks.
54 |
55 | Think of Firestore as the next generation of the Realtime Database.
56 |
57 | It has great client libraries.
58 |
59 | It has security rules.
60 |
61 | It works with Cloud Functions for Firebase.
62 |
63 | But Firestore is structured data.
64 |
65 | And Firestore supports complex queries.
66 |
67 | And Firestore scales based on your result set, not on your collection's record count.
68 |
69 | So let's back up and cover these differences one by one.
70 |
71 | First off, Firestore is a document/collection database.
72 |
73 | If you've used Google Cloud Datastore or MongoDB then you'll be familiar.
74 |
75 | There's a strict pattern to Firestore.
76 |
77 | First, you define a collection. Then you add documents.
78 |
79 | And each document supports sub-collections, which contain their own documents.
80 |
81 | So you can nest data much like you did in the Realtime Database, but it's much more structured.
82 |
83 | Think collection... then document... then collection... then document.
84 |
85 | It's a new pattern, but it's not hard to figure out.
86 |
87 | Second, Firestore has client libraries just like the Realtime Database.
88 |
89 | The Firestore client library enables you to execute single queries or listen to a document or collection for changes.
90 |
91 | Unlike the Realtime Database, your Firestore queries can have multiple where and orderBy statements.
92 |
93 | And unlike the Realtime Database, your Firestore queries remain performant for massive collections.
94 |
95 | The Realtime Database gets cranky if you force it to query over millions of records.
96 |
97 | Firestore doesn't care how complicated your query is or how many records are in the collection.
98 |
99 | But Firestore DOES care about how many records you return.
100 |
101 | This is one of the main differences between Firebase and Firestore.
102 |
103 | The Realtime Database always billed you based on connection count and data transfer.
104 |
105 | Firestore does not bill you by connected client count.
106 |
107 | But Firestore does bill you by the volume of data transferred.
108 |
109 | AND Firestore bills you by your read, write and delete counts.
110 |
111 | So every record that you pull from the database counts against your reads.
112 |
113 | Don't get too nervous, because reads are six cents for 100 thousand;
114 |
115 | however, you need to recognize that Firestore scales based on the result set.
116 |
117 | So if the feature you're building has lots of fast, small reads and writes, stick to the Realtime Database.
118 |
119 | But you'll find that most app features are much easier to build on Firestore.
120 |
121 | I've found myself using Firestore for about 95% of my app's data needs.
122 |
123 | I keep the Realtime Database in my back pocket for those edge cases where it's still the best solution.
124 |
125 | But more and more I'm using Firestore for all of my new features.
126 |
127 | I hope that clears up the differences between Firebase and Firestore.
128 |
129 | I'm sure there will be questions, so fire away in the comments below.
130 |
131 | Thanks for watching!
132 |
133 | And make sure to subscribe to get updates on my new videos...
134 |
135 | and I'll let you know how my course is going :)
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
--------------------------------------------------------------------------------
/scripts/YouTube/0001.003 - introducing full-stack firebase.txt:
--------------------------------------------------------------------------------
1 | Hello YouTube!
2 |
3 | It's Chris Esplin again, haunting your suggested videos feed!
4 |
5 | This will be a short update on what I've been doing for the last year.
6 |
7 | In the Summer of 2017 I was approached by some great folks from `Udemy dot com`.
8 |
9 | They were interested in publishing a Firebase course to their platform...
10 |
11 | ...and thought that I might be interested in collaborating on a course with Juarez Filho.
12 |
13 | Juarez and I have been in the Google Developer Expert program for a few years...
14 |
15 | ...and we both specialize in Firebase for web.
16 |
17 | We use the Firebase platform every day and know the space pretty well.
18 |
19 | So I said "yes", understanding that I was in for a lot of work.
20 |
21 | I use time-tracking software every day...
22 |
23 | ...so I can confidently say that I've spent over 450 hours on this project over the last year.
24 |
25 | I had no idea what I was getting into.
26 |
27 | The problem is that I couldn't stomach the thought of knocking the course out quickly.
28 |
29 | I've been unhappy with my video production skills for a while now, and I wanted to solve that.
30 |
31 | So I bought a bunch of video equipment and software and started teaching myself.
32 |
33 | I worked on the project for three hours every morning before work and on Saturdays...
34 |
35 | ...except for vacations and breaks for a bit of freelance work.
36 |
37 | Anyway, the reason we're here is because I've got over 40 videos and I'm anxious to ship them!
38 |
39 | We're talking about a full-blown, two-and-a-half hour video course on `udemy dot com`.
40 |
41 | I'm a web developer, so this is Firebase for web, not Android or iOS.
42 |
43 | That's not to say that the fundamentals won't apply if you're a native developer...
44 |
45 | ...but I built the demo project in React and used the JavaScript SDK for everything.
46 |
47 | You can start learning with the free companion site, `full stack firebase dot com`.
48 |
49 | I've used `full stack firebase dot com` as a place to outline the material...
50 |
51 | ...because you've got to write it all down before you can start shooting videos.
52 |
53 | So start at `full stack firebase dot com` and you'll find links to purchase the course on Udemy.
54 |
55 | You'll also find a bunch of introductory modules about high-level Firebase concepts.
56 |
57 | We've covered serverless concepts and how to think about the Firebase ecosystem.
58 |
59 | And of course you'll find modules on each of the big Firebase platform features.
60 |
61 | These modules include the Firebase command-line interface, Authentication, Firestore...
62 |
63 | ...the Realtime Database, Cloud Functions for Firebase, Firebase Storage...
64 |
65 | ...Firebase Cloud Messaging, and Firebase Hosting.
66 |
67 | Each module starts with an introduction and a walkthrough to demonstrate the feature in action.
68 |
69 | Next we implement the feature in our demo app.
70 |
71 | The original plan was for Juarez to write a demo app in Angular and I'd do one in React.
72 |
73 | Juarez is behind schedule, so the Angular demos aren't ready;
74 |
75 | however, my React demo app is live at `react dot fullstackfirebase dot com`...
76 |
77 | ...and you'll be able to deploy your own version of it when you take the Udemy course.
78 |
79 | Don't get hung up on the fact that it's in React, because you won't need to code any React.
80 |
81 | The Firebase SDK is all vanilla JavaScript, so my integrations are vanilla JS as well.
82 |
83 | I would have done the entire app in vanilla JavaScript...
84 |
85 | ...but that would have added a few hundred more hours to the development process.
86 |
87 | So let's wrap this up.
88 |
89 | I am not giving up on YouTube.
90 |
91 | I've just been wholly consumed by learning video production and making a Firebase course.
92 |
93 | `full stack firebase dot com` is still a work in progress, but it's free for everyone.
94 |
95 | The Udemy course isn't free, but it isn't expensive either.
96 |
97 | I'm confident that you won't find a more comprehensive course on Firebase for web.
98 |
99 | And now that I've spent a few hundred hours learning to produce videos and screencasts...
100 |
101 | ...I'm anxious to dive back into YouTube.
102 |
103 | So smash that like button.
104 |
105 | Hit it three times if you can.
106 |
107 | Just make sure that it's an odd number of times so that YouTube registers the "like" correctly.
108 |
109 | I'll hang out in the comments to respond to questions...
110 |
111 | ...and as always, make sure to subscribe for the latest Firebase tips and tricks!
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
--------------------------------------------------------------------------------
/scripts/YouTube/0001.004 - firestore sub-collections.txt:
--------------------------------------------------------------------------------
1 | Greetings YouTube!
2 |
3 | If you've been keeping up on Firebase in the last year then you're likely using Firestore.
4 |
5 | Firestore is a bit of a successor to the original Firebase Realtime Database.
6 |
7 | After Google purchased Firebase in October of 2014...
8 |
9 | ...Firebase had to move over to Google infrastructure.
10 |
11 | That's a ton of work, but once you're on Google infrastructure, you're on Google infrastructure!
12 |
13 | So you might as well design a new database from scratch that crushes everything that came before.
14 |
15 | And that's how we got Firestore.
16 |
17 | I've talked about Firestore in the past...
18 |
19 | ...so review those videos or check out `full stack firebase dot com` for the Firestore introduction.
20 |
21 | I'd like to talk at a high level about Firestore sub-collections.
22 |
23 | First, we need to review the Firestore data model.
24 |
25 | Firestore is a document/collection database.
26 |
27 | Documents hold whatever JSON data you'd like, but they must live within a collection.
28 |
29 | A document can have any number of sub-collections with their own documents.
30 |
31 | And you can keep nesting your data within sub-collections to your heart's content.
32 |
33 | But that would be a horrible mistake.
34 |
35 | In fact, I haven't found a great use case for sub-collections quite yet.
36 |
37 | First off, you can easily save embedded JSON objects within your documents...
38 |
39 | ...so it's not necessary to make a sub-collection to nest data within a document.
40 |
41 | And second, sub-collections are easily orphaned.
42 |
43 | What do I mean by orphaned???
44 |
45 | I mean that if you delete a document's data without deleting it's sub-collections...
46 |
47 | ...you can no longer query the document...
48 |
49 | ...so you might lose your reference to it, and lose track of its sub-collections.
50 |
51 | This deserves some extra explanation.
52 |
53 | If I have a collection called `foods`, I can query all of the documents in my `foods` collection.
54 |
55 | Imagine that I have a `food` document named `gelato`.
56 |
57 | My `gelato` document has attributes for `color`, `calories` and `deliciousnessRating`.
58 |
59 | I want to track the ingredients in my gelato, so I create an `ingredients` sub-collection.
60 |
61 | When I query my `foods` I get an object back named `gelato`...
62 |
63 | ...with `color`, `calories` and `deliciousnessRating` attributes.
64 |
65 | But I don't get the `ingredients` sub-collection.
66 |
67 | I only get the `ingredients` sub-collection if I make a separate query for it.
68 |
69 | And I have to just know that it's there.
70 |
71 | There's no hint that my `gelato` document has sub-collections.
72 |
73 | So I can lose track of my `ingredients` sub-collection by forgetting that it exists.
74 |
75 | Now imagine that I delete my gelato document for some reason.
76 |
77 | My `gelato` document is gone, but I've forgotten to delete my `ingredients` sub-collection.
78 |
79 | Because, get this... I have to manually delete a document's sub-collections.
80 |
81 | And to add insult to injury...
82 |
83 | ...since I deleted the `gelato` document, it no longer shows up in my `foods` queries.
84 |
85 | So now I don't know that `gelato` ever existed, but the `ingredients` sub-collection is still there.
86 |
87 | You can see these orphaned sub-collections by clicking through the Firestore web console.
88 |
89 | But you have to click through every single document to find them...
90 |
91 | ...because orphaned sub-collections don't show up when you query their parents.
92 |
93 | This is garbage.
94 |
95 | I'm confident that the Firebase team knows of this problem and has some plan to address it...
96 |
97 | ...because Firestore is still in beta of course...
98 |
99 | ...and I'm thankful to have Firestore even with it's wacky sub-collection system.
100 |
101 | Just don't get suckered by sub-collections.
102 |
103 | They have their uses for sure.
104 |
105 | I've used them to cascade security rules and it's been great...
106 |
107 | ...but sub-collections are still iffy as a cornerstone of your data model.
108 |
109 | The good news is that you don't need sub-collections to build your app on Firestore.
110 |
111 | And they'll likely get more useful in time, so I'm hopeful.
112 |
113 | Let me know what you think about Firestore in the comments.
114 |
115 | I'll hang out and answer questions as always...
116 |
117 | ...and don't forget to smash those "like" and "subscribe" buttons.
118 |
119 | If you're already subscribed, maybe unsubscribe and subscribe again...
120 |
121 | ...just for the satisfaction of clicking that fantastic "subscribe" button one more time.
122 |
123 |
124 |
125 |
126 |
--------------------------------------------------------------------------------
/scripts/YouTube/0001.005 - firebase security - a response.txt:
--------------------------------------------------------------------------------
1 | I pay close attention to the Firebase ecosystem...
2 |
3 | ...so my Google News feed often has Firebase- and Google-related articles in it.
4 |
5 | A few weeks ago I saw an article pass through my feed about Firebase apps leaking data.
6 |
7 | It was coverage of some security research by a company named Appthority.
8 |
9 | Appthority did an audit of thousands of Android and iOS apps and found some serious problems.
10 |
11 | These apps had all implemented Firebase, but failed to implement Firebase security rules.
12 |
13 | So these apps' Firebase databases are basically public for everyone to read.
14 |
15 | I thought, "wow, that's really horrible... I sure hope they get that fixed!"...
16 |
17 | ...and I forgot about it.
18 |
19 | But in the last few days the coverage has gotten heavier...
20 |
21 | ...and it's entered into clickbait territory.
22 |
23 | When the clickbait farms start to recycle content, the coverage goes from "ok" to "horrible".
24 |
25 | The details of the story suffer, because the clickbait farms are churning out articles...
26 |
27 | ...without even a cursory understanding of what they're writing about.
28 |
29 | So I'd like to clear this situation up a bit.
30 |
31 | Just be to one-hundred percent up front, I am not speaking for anyone but myself.
32 |
33 | These are my opinions that I'm talking about because the clickbait is misleading.
34 |
35 | So what is actually happening with these data leaks?
36 |
37 | It's simple.
38 |
39 | Bad developers are lazy and believe in security-through-obscurity.
40 |
41 | Firebase has given them all of the tools that they need, but they haven't used them.
42 |
43 | And as a result, apps by lazy, incompetent developers are leaking data all over the web.
44 |
45 | This happens because Firebase is a back-end as a service.
46 |
47 | This necessitates that the Firebase database is publicly accessible.
48 |
49 | Anyone can make requests to your Firebase database, both the Realtime Database and Firestore.
50 |
51 | So Firebase has Security Rules that you write to lock down your databases.
52 |
53 | These rules are, admittedly, the weakest part of the Firebase platform.
54 |
55 | I am not implying that the security itself is weak, because it's bulletproof.
56 |
57 | But Security Rules are difficult for developers to understand...
58 |
59 | ...because they solve a complex set of problems.
60 |
61 | I've noticed that Firebase's default security rules have become more strict over the years.
62 |
63 | You now have to manually override them to make your database public.
64 |
65 | You're supposed to replace the default rule with your app-specific rules to lock your data.
66 |
67 | It's a little like changing the admin password on your new router.
68 |
69 | People don't think anything will ever happen to them...
70 |
71 | ...so the vast majority of routers still use their publicly-discoverable default passwords.
72 |
73 | Likewise, bad developers don't think anything will ever happen to them...
74 |
75 | ...so they override Firebase's Security Rules and make their apps publicly accessible.
76 |
77 | A publicly-accessibly app is easier to develop on...
78 |
79 | ...because you never run afoul of your own Security Rules.
80 |
81 | And that's fine if you're writing a little demo app or an internal prototype with dummy data.
82 |
83 | But it's become clear that there are a ton of bad developers out there...
84 |
85 | ...and that these devs shipped their apps without ever locking them back up.
86 |
87 | If you're interested in stealing, there are a ton of insecure apps on the web.
88 |
89 | And some of them are poorly configured Firebase apps.
90 |
91 | If you've been a bad developer, please write some security rules.
92 |
93 | I'm happy to help you sort them out.
94 |
95 | In fact, I've written some tutorials over on `full stack firebase dot com` that will prove useful.
96 |
97 | And for everyone else...
98 |
99 | ...thank you for taking basic security measures and locking down your Firebase apps.
100 |
101 | Data security is no joke.
102 |
103 | We have to take our responsibility as developers very seriously.
104 |
105 | I don't want to work in a highly-regulated industry...
106 |
107 | ...and bad data security, even if it's inadvertent, will drag us all down.
108 |
109 | And if you somehow conned me into installing an insecure app on my phone...
110 |
111 | ...shame.
112 |
113 | Shame.
114 |
115 | Shame.
116 |
117 | Shame.
118 |
119 |
120 |
121 |
122 |
123 |
--------------------------------------------------------------------------------
/scripts/YouTube/0001.006 - channel introduction.txt:
--------------------------------------------------------------------------------
1 | How To Firebase is all about building production-worthy Firebase apps for web.
2 |
3 | Firebase got its start back in 2011 as a Y Combinator startup.
4 |
5 | It was acquired by Google just three years later in October of 2014.
6 |
7 | The Firebase platform has grown from a fun toy to use for prototype apps...
8 |
9 | ...to the premiere, planet-scale app development platform.
10 |
11 | We're talking about taking your apps from prototype to production without touching the database!
12 |
13 | Firebase has matured into a monster of a product, and I want to scream from the roof tops...
14 |
15 | ...if you're not considering Firebase for your next project, you are missing a golden opportunity!
16 |
17 | But a game-changing development platform like Firebase has a bit of a learning curve.
18 |
19 | The Firebase team works hard to lower that barrier to entry...
20 |
21 | ...but developers who are steeped in SQL and other NoSQL datastores often struggle at first.
22 |
23 | So let me be your guide!
24 |
25 | I use Firebase for all of my projects.
26 |
27 | I built Calligraphy.org on top of Firebase and have run it profitably since 2012.
28 |
29 | I've built countless custom apps for myself and clients over the years.
30 |
31 | I subscribe to all of the Firebase newsletters and read the blog posts...
32 |
33 | ...and I summarize what I've learned here on YouTube, for your viewing pleasure.
34 |
35 | These are not adorable cat videos.
36 |
37 | I can't help that it's programming...
38 |
39 | ...but smash that subscribe button anyway!
40 |
41 | I will make Firebase as riveting as possible and earn your YouTube views.
42 |
--------------------------------------------------------------------------------
/scripts/YouTube/0001.008 - custom claims.txt:
--------------------------------------------------------------------------------
1 | I'd like to talk about my favorite feature of Firebase Authentication.
2 |
3 | You probably haven't heard of it...
4 |
5 | ...because it's buried in one of the "getting started" guides in the Firebase docs...
6 |
7 | ...and nobody reads ALL OF THE DOCS!
8 |
9 | I only discovered custom claims when I complained about the lack of user role management.
10 |
11 | I mean, if I want to tag a user as an admin, do I have to make a database entry?
12 |
13 | Because if that's the case, I have to query the database every time I authenticate a user...
14 |
15 | ...and while I've done that for a long time...
16 |
17 | ...it's a slow, cumbersome operation.
18 |
19 | So I was whining, I can't remember if it was online or at a Firebase event...
20 |
21 | ...and a Firebase team member mentioned Custom Claims as an easy solution to my problem.
22 |
23 | Why is this feature hidden!!!
24 |
25 | Every Firebase app should be using Custom Claims, and it's buried deep in the docs!
26 |
27 | Any non-trivial app eventually needs user roles.
28 |
29 | I need to mark users as administrators or managers or moderators or just plain paid-up users.
30 |
31 | And Custom Claims allows me to set simple user attributes directly on my user's JWT.
32 |
33 | A JWT is a Json Web Token, which is the `currentUser` object in Firebase Authentication.
34 |
35 | So every time I authenticate on the client I get a `currentUser` JWT...
36 |
37 | ...and if I've set custom claims on my user...
38 |
39 | ...I can extract the custom claims from the user JWT.
40 |
41 | I have a sample Cloud Function that does just this, and I'll link to the files below.
42 |
43 | So let's talk through that code and I'll show it all in action.
44 |
45 | We'll get started with my Cloud Function called `authorization on create`.
46 |
47 | `authorization on create` is triggered by new user creation in Firebase Authentication.
48 |
49 | I'm saving all of my custom claims data by user email address in the Realtime Database...
50 |
51 | ...so the first thing to do is to get that data from the RTDB.
52 |
53 | Once I have the relevant claims data for my user, I just need to set it.
54 |
55 | That's an easy call to `firebase dot auth dot setCustomUserClaims`.
56 |
57 | I just pass in the user's UID that I get from the JWT and the claims object.
58 |
59 | The claims object can be anything really...
60 |
61 | ...but it must be under 1000 bytes...
62 |
63 | ...and you should only use it for access-control.
64 |
65 | There are performance implications to trying to save too much data in a custom claim...
66 |
67 | ...so just follow best-practices and keep that sort of data in the RTDB or Firestore.
68 |
69 | In this case I want to set `isAdmin` and `isModerator` flags on my user.
70 |
71 | I developed this Cloud Function with test-driven development methodologies...
72 |
73 | ...so I am very proud to say that it worked the very first time I deployed it.
74 |
75 | To prove that this works, I'll go ahead and delete my user from Firebase Authentication.
76 |
77 | Now I'll register a new user and we can see that the claims are not there yet.
78 |
79 | I can refresh my page and the claims still won't be there...
80 |
81 | ...so I'll have to sign out and sign back in...
82 |
83 | ...and there they are.
84 |
85 | My `isAdmin` and `isModerator` flags are set and I'm ready to start writing my admin dashboard.
86 |
87 | I'm getting my custom claims data by calling `currentUser dot getIdTokenResult`.
88 |
89 | It's an async function that returns an `idTokenResult`.
90 |
91 | The `idTokenResult` has a `claims` attribute with the custom claims as children.
92 |
93 | Getting and setting custom claims is dead simple.
94 |
95 | All of the complexity comes from writing the Cloud Function to do it...
96 |
97 | ...so go ahead and copy/paste my function to get started!
98 |
99 | I write very opinionated Cloud Functions code...
100 |
101 | ...so take my code with a grain of salt.
102 |
103 | You don't need to complicate your Cloud Functions as much as I do.
104 |
105 | Go ahead and keep it simple, and I hope you love custom claims.
106 |
107 | They're fantastic.
108 |
109 | I'm just mad that it took me so long to find them.
110 |
111 |
112 |
113 |
114 |
115 |
116 | I don't own any silly pets, and I'm just not that funny...
117 |
118 | ...so thanks for watching me talk about programming.
119 |
120 | This is a boutique channel...
121 |
122 | ...meaning that it's super niche and kinda tiny.
123 |
124 | But tiny YouTube channels are great...
125 |
126 | ...especially if you really, really like writing code.
127 |
128 | Every subscription, like and comment helps...
129 |
130 | ...but seriously, I'm going to shoot videos anyway.
131 |
132 | You can't stop me.
133 |
134 | It's too late.
135 |
136 |
137 |
138 |
--------------------------------------------------------------------------------
/scripts/YouTube/0001.009 - outro.txt:
--------------------------------------------------------------------------------
1 | I don't own any silly pets, and I'm just not that funny...
2 |
3 | ...so thanks for watching me talk about programming.
4 |
5 | This is a boutique channel...
6 |
7 | ...meaning that it's super niche and kinda tiny.
8 |
9 | But tiny YouTube channels are great...
10 |
11 | ...especially if you really, really like writing code.
12 |
13 | Every subscription, like and comment helps...
14 |
15 | ...but seriously, I'm going to shoot videos anyway.
16 |
17 | You can't stop me.
18 |
19 | It's too late.
20 |
21 |
--------------------------------------------------------------------------------