Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated link to Faker.js repository #1469

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 16 additions & 16 deletions content/lessons/algolia-cloud-functions/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ publishdate: 2019-08-25T10:43:13-07:00
author: Jeff Delaney
draft: false
description: Build a pipeline for full-text search indexing with Firestore Cloud Functions
tags:
tags:
- node
- algolia
- firestore
Expand All @@ -15,7 +15,7 @@ youtube: dTXzxSlhTDM
github: https://github.com/fireship-io/203-algolia-firestore-mvp
---

One of the most commonly encountered limitations of [Cloud Firestore](https://firebase.google.com/docs/firestore) (and GCP) is [full-text search](https://en.wikipedia.org/wiki/Full-text_search). This functionality is essential if you need to query complex text patterns in a database or filter results by multiple dynamic properties. My favorite solution to this limitation is [Algolia](https://www.algolia.com/), which provides a powerful, developer-friendly, search & discovery API. In the following lesson you will learn how to sync your Firestore data to an Algolia index via Cloud Functions.
One of the most commonly encountered limitations of [Cloud Firestore](https://firebase.google.com/docs/firestore) (and GCP) is [full-text search](https://en.wikipedia.org/wiki/Full-text_search). This functionality is essential if you need to query complex text patterns in a database or filter results by multiple dynamic properties. My favorite solution to this limitation is [Algolia](https://www.algolia.com/), which provides a powerful, developer-friendly, search & discovery API. In the following lesson you will learn how to sync your Firestore data to an Algolia index via Cloud Functions.



Expand All @@ -30,7 +30,7 @@ Make sure you are at least using the Firebase Blaze plan because this will enabl

### Initialize Cloud Functions

First, initialize Cloud Functions in your project with the Firebase Tools CLI. This lesson uses vanilla JS, but feel free to select TypeScript if you prefer.
First, initialize Cloud Functions in your project with the Firebase Tools CLI. This lesson uses vanilla JS, but feel free to select TypeScript if you prefer.

{{< file "terminal" "command line" >}}
```text
Expand All @@ -40,7 +40,7 @@ firebase init functions

### Install Algolia

Indexing tasks can be handled in Node with the [Algolia JS SDK](https://www.algolia.com/doc/api-client/getting-started/install/javascript/?language=javascript) package.
Indexing tasks can be handled in Node with the [Algolia JS SDK](https://www.algolia.com/doc/api-client/getting-started/install/javascript/?language=javascript) package.

```text
cd functions
Expand All @@ -49,17 +49,17 @@ npm install algoliasearch

### Create an Index

Algolia provides a guided UI for building indexes that support full-text search.
Algolia provides a guided UI for building indexes that support full-text search.

{{< figure src="img/create-index.png" caption="Create an index named customers on the Algolia dashboard" >}}

### Add the Algolia API Key to Firebase

You can find your credentials under the *API Keys* tab. Your backend code requires the **Application ID** and **Admin API Key**. Keep the admin key safe and do not expose it to the public.
You can find your credentials under the *API Keys* tab. Your backend code requires the **Application ID** and **Admin API Key**. Keep the admin key safe and do not expose it to the public.

{{< figure src="img/api-keys.png" caption="You need the Algolia App ID and Admin API Key" >}}

Now set the API key and template ID in the Firebase project with the following command.
Now set the API key and template ID in the Firebase project with the following command.

{{< file "terminal" "command line" >}}
```text
Expand All @@ -68,7 +68,7 @@ firebase functions:config:set algolia.app=YOUR_APP_ID algolia.key=ADMIN_API_KEY

## Algolia Cloud Functions

Setup the Cloud Functions environment by initializing the Algolia client and index.
Setup the Cloud Functions environment by initializing the Algolia client and index.

{{< file "js" "functions/index.js" >}}
```js
Expand All @@ -92,9 +92,9 @@ exports.deleteFromIndex; // TODO

### Add Record to Algolia

Our goal is to duplicate a subset of data from the Firestore customer document to Algolia. The first step is to add a new record to the index with the `onCreate` Firestore event.
Our goal is to duplicate a subset of data from the Firestore customer document to Algolia. The first step is to add a new record to the index with the `onCreate` Firestore event.

💡 Tip. Only index data in Algolia that is actually useful for searching and/or displaying in search results. Do NOT index personally identifiable information (PII), like phone numbers and email addresses. You may not need to duplicate the entire document.
💡 Tip. Only index data in Algolia that is actually useful for searching and/or displaying in search results. Do NOT index personally identifiable information (PII), like phone numbers and email addresses. You may not need to duplicate the entire document.

```js
exports.addToIndex = functions.firestore.document('customers/{customerId}')
Expand All @@ -111,7 +111,7 @@ exports.addToIndex = functions.firestore.document('customers/{customerId}')

### Update a Record in Algolia

If the Firestore document data changes, we want these changes reflected in the index and search results. We can easily handle this task with an `onUpdate` function.
If the Firestore document data changes, we want these changes reflected in the index and search results. We can easily handle this task with an `onUpdate` function.

```js
exports.updateIndex = functions.firestore.document('customers/{customerId}')
Expand All @@ -125,19 +125,19 @@ exports.updateIndex = functions.firestore.document('customers/{customerId}')

### Delete a Record

When a Firestore document is deleted, we must also remove it from the search index. In this case, we simply pass the objectID to Algolia within an `onDelete` function.
When a Firestore document is deleted, we must also remove it from the search index. In this case, we simply pass the objectID to Algolia within an `onDelete` function.

```js
exports.deleteFromIndex = functions.firestore.document('customers/{customerId}')

.onDelete(snapshot =>
.onDelete(snapshot =>
index.deleteObject(snapshot.id)
);
```

### Deploy

Deploy your functions and test them from the Firebase console, or follow the seeding instructions in the next section.
Deploy your functions and test them from the Firebase console, or follow the seeding instructions in the next section.

{{< file "terminal" "command line" >}}
```text
Expand All @@ -146,7 +146,7 @@ firebase deploy --only functions

## Optional: Seed the Database

In the video you saw how I quickly seeded Firestore with dummy data, which was accomplished with [Faker](https://github.com/marak/Faker.js/) and the Firebase Admin SDK. Create a vanilla node script in the functions directory that sends writes to the database.
In the video you saw how I quickly seeded Firestore with dummy data, which was accomplished with [Faker](https://github.com/faker-js/faker) and the Firebase Admin SDK. Create a vanilla node script in the functions directory that sends writes to the database.
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I edited the file with cloud VS Code, provided by the Github platform, which automatically improved the Prettier formatting.
This line includes the actual url change!


{{< file "js" "functions/seed.js" >}}
```js
Expand Down Expand Up @@ -177,5 +177,5 @@ node seed.js
```


This post first appeared as [Episode 109 Algolia Firestore on AngularFirebase.com](https://angularfirebase.com/lessons/algolia-firestore-quickstart-with-firebase-cloud-functions/) and has been fully updated with the latest best practices.
This post first appeared as [Episode 109 Algolia Firestore on AngularFirebase.com](https://angularfirebase.com/lessons/algolia-firestore-quickstart-with-firebase-cloud-functions/) and has been fully updated with the latest best practices.

36 changes: 18 additions & 18 deletions content/lessons/firebase-emulator-advanced/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@ publishdate: 2020-05-31T19:11:38-07:00
author: Jeff Delaney
draft: false
description: Advanced techniques for generating mock data and testing with the Firebase emulator suite
tags:
tags:
- firebase
- productivity
- testing
- pro

pro: true
vimeo: 424882834
# youtube:
# github:
# youtube:
# github:
# disable_toc: true
# disable_qna: true

Expand Down Expand Up @@ -52,7 +52,7 @@ How do you use emulated Cloud Functions and Firestore in a frontend app? When de
{{< file "js" "client-side.js" >}}
```javascript
firebase.initializeApp(yourFirebaseConfig);


if (location.hostname === "localhost") {

Expand All @@ -67,7 +67,7 @@ How do you use emulated Cloud Functions and Firestore in a frontend app? When de

### Backend Firebase Admin

If using Firebase Admin with Node.js, you can set an environment variable when not in production.
If using Firebase Admin with Node.js, you can set an environment variable when not in production.

{{< file "js" "server-side.js" >}}
```javascript
Expand All @@ -82,16 +82,16 @@ if (process.env.NODE_ENV !== 'production') {

### What cannot be Emulated?

Auth, Storage, and FCM are not currently supported. If you need to create a large number of mock records for these services, consider creating a second "sandbox" Firebase project.
Auth, Storage, and FCM are not currently supported. If you need to create a large number of mock records for these services, consider creating a second "sandbox" Firebase project.


## Mock Data

The emulator makes the Firebase Admin SDK available on the browser `window`. This means you can just call `firestore.doc(...).set(...)` from a client-side script or the browser console.
The emulator makes the Firebase Admin SDK available on the browser `window`. This means you can just call `firestore.doc(...).set(...)` from a client-side script or the browser console.

### Generate Fake Firestore Data Quickly

We can quickly generate mock data by injecting [Faker.js](https://github.com/marak/Faker.js/) into a browser script. The script appends a button to the UI, then tells Firestore to create 100 user documents with fake data. Run it by simply pasting this code into the browser console.
We can quickly generate mock data by injecting [Faker.js](https://github.com/faker-js/faker) into a browser script. The script appends a button to the UI, then tells Firestore to create 100 user documents with fake data. Run it by simply pasting this code into the browser console.
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I edited the file with cloud VS Code, provided by the Github platform, which automatically improved the Prettier formatting.
This line includes the actual url change!


{{< file "js" "browser console" >}}
```javascript
Expand Down Expand Up @@ -126,14 +126,14 @@ We can quickly generate mock data by injecting [Faker.js](https://github.com/mar

### Run the Script Automatically

You can run this script each time you visit the `localhost:4000/firestore/*` URL with a browser plugin called [TamperMonkey](https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo).
You can run this script each time you visit the `localhost:4000/firestore/*` URL with a browser plugin called [TamperMonkey](https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo).

{{< figure src="img/emulator-fake-data.png" caption="Use TamperMonkey to run the script automatically" >}}


## PubSub

[Pub/Sub](https://cloud.google.com/pubsub/) is a secure way to send messages between Google Cloud services. To create messages, install the Node.js client.
[Pub/Sub](https://cloud.google.com/pubsub/) is a secure way to send messages between Google Cloud services. To create messages, install the Node.js client.

{{< file "terminal" "command line" >}}
```text
Expand All @@ -142,7 +142,7 @@ npm i @google-cloud/pubsub

### Create and Send Messages

Below we have an HTTP function used to publish test messages. First, it checks if a topic exists, and if not, creates it. Next, it sends the JSON payload to its subscribers. I would recommend calling this function from an HTTP client like Postman or Insomnia (see video).
Below we have an HTTP function used to publish test messages. First, it checks if a topic exists, and if not, creates it. Next, it sends the JSON payload to its subscribers. I would recommend calling this function from an HTTP client like Postman or Insomnia (see video).

```javascript
const { PubSub } = require('@google-cloud/pubsub');
Expand All @@ -155,7 +155,7 @@ exports.sendTestMessage = functions.https.onRequest(async (req, res) => {


const [exists] = await pubsubClient.topic(topic).exists();

if (!exists) {
await pubsubClient.createTopic(topic);
}
Expand All @@ -169,7 +169,7 @@ exports.sendTestMessage = functions.https.onRequest(async (req, res) => {

### Receive Messages

Handle messages to a topic with a Pub/Sub Cloud Function.
Handle messages to a topic with a Pub/Sub Cloud Function.

```javascript
exports.handleMessage = functions.pubsub.topic('test').onPublish( async (message, context) => {
Expand All @@ -186,27 +186,27 @@ exports.handleMessage = functions.pubsub.topic('test').onPublish( async (message

### Run Scheduled Jobs

The emulator does not currently run cron jobs for your scheduled functions. However, you can test the logic in your function by triggering the associated Pub/Sub topic, such as `firebase-schedule-YOUR_FUNCTION_NAME`.
The emulator does not currently run cron jobs for your scheduled functions. However, you can test the logic in your function by triggering the associated Pub/Sub topic, such as `firebase-schedule-YOUR_FUNCTION_NAME`.

```javascript
exports.someBackgroundJob = functions.pubsub.schedule('* * * * *').onRun( ctx => { ... });
```

For example, this function can be triggered by sending a message to `firebase-schedule-someBackgroundJob`. If you really want to test a schedule, consider creating a script with [node-cron](https://www.npmjs.com/package/node-cron).
For example, this function can be triggered by sending a message to `firebase-schedule-someBackgroundJob`. If you really want to test a schedule, consider creating a script with [node-cron](https://www.npmjs.com/package/node-cron).

## Testing

### End-to-End with Cypress

You can easily add end-to-end (E2E) testing to any frontend project with Cypress.
You can easily add end-to-end (E2E) testing to any frontend project with Cypress.

{{< file "terminal" "command line" >}}
```text
cd frontend-app
npm install cypress -D
```

Create a file for your spec.
Create a file for your spec.

{{< file "js" "cypress/integration/example-spec.js" >}}
```javascript
Expand Down Expand Up @@ -274,4 +274,4 @@ E2E testing is not suitable for all scenarios. In some cases, you may to [unit t

### Firestore Rules Unit Tests

It can also be beneficial to [test Firestore security rules](https://fireship.io/lessons/testing-firestore-security-rules-with-the-emulator/).
It can also be beneficial to [test Firestore security rules](https://fireship.io/lessons/testing-firestore-security-rules-with-the-emulator/).
Loading