- Clone and install
- Set up new instance
- Run locally
- Build and deploy
- Lint and fix
- Import production data from Cloud Firestore to local Firestore
- Import production data
- Automated Backup with Cloud Functions
- Slack Integration
Clone repository and run install:
npm install && cd ./functions && npm install && cd ..Install Firebase CLI:
npm install -g firebase-toolsFollow this guide to set up a new clean instance of the OKR-tracker.
- Create a Google Firebase project.
- Initialize the project with Firebase CLI
- Create a Google service account
- From the Project Overview, select Service accounts
- Click Generate new private key
This key is used for fetching data from Google Sheets (for automatically updating key results). In order to fetch data from Google Sheets, you must set up environment variables for Firebase Functions:
firebase functions:config:set
sheets.email="<service account email>"
sheets.key="<service account private key>"Note: The private key string needs to have actual line breaks as opposed to \\n because of an issue with how Firebase stores environment variables. Read more.
We use Google Auth to authenticate users and this needs to be enabled in the Firebase Console.
- Navigate to your project in the Firebase console
- Press the Authentication-button in the side menu
- Sign-in Method-tab
- Enable Google Auth
Get your Firebase SDK snippet from your Firebase Console:
- Navigate to Project settings
- Under Your apps, find Firebase SDK snippet and press Config
- Copy the following secrets to a
.env.productionfile in the root directory.
| Secret | Description |
|---|---|
VUE_APP_API_KEY |
from SDK snippet |
VUE_APP_AUTH_DOMAIN |
from SDK snippet |
VUE_APP_DATABASE_URL |
from SDK snippet |
VUE_APP_PROJECT_ID |
from SDK snippet |
VUE_APP_STORAGE_BUCKET |
from SDK snippet |
VUE_APP_MESSAGING_SENDER_ID |
from SDK snippet |
VUE_APP_APP_ID |
from SDK snippet |
VUE_APP_MEASUREMENT_ID |
from SDK snippet |
VUE_APP_SHEETS_SERVICE_ACCOUNT |
<service account email> |
VUE_APP_I18N_LOCALE |
nb-NO | en-US |
firebase use --addThe local development environment uses Firebase Emulator Suite for Firestore and Cloud Functions. The Auth module is still remote, so you will need to add your own email address to the emulated store before getting started.
Start the Firebase Emulator:
firebase emulators:startIn a new terminal window, start run the local web server:
npx vue-cli-service serveThen whitelist your own email address by manually inserting it to the emulated Firestore:
- Navigate to http://localhost:7777/firestore
- Click Start collection
- Type 'users' as collection ID and hit Next
- Insert your own Google Account-email as Document ID. Create a new field 'admin' with type boolean and value
trueand a new field 'email' with type string and the same email address as value. - Click Save
Confirm the access by visiting http://localhost:8080/, press Sign in with Google and select your Google Account.
After successfully logging in to the OKR Tracker, navigate to the Admin panel. Here you can create new organisations, departments and products to use as your mock data. On each object you can also create periods, objectives, key results and KPIs.
To export your mock data run the following command:
firebase emulators:export ./mockTo update existing mock data, simply run the export command above and confirm overwrite existing export.
Retrieve current Firebase environment configuration. This is needed for certain cloud functions to function locally.
firebase functions:config:get > ./functions/.runtimeconfig.jsonStart Firebase emulators, import mock data and run the development server:
npm run devBuild and deploy to production:
npm run deployRun linter
npm run lintLint styles
npm run lint:styleAutomatically fix lint issues
npm run lint:style:fixBased on this tutorial with a few differences for our use case.
The newest version of the OKR Tracker uses the Firebase Local Emulator Suite, where you can play and test your data without being afraid of production changes. It is still in the early stages, which means that auth is still handled by the cloud firebase and not locally.
When you start up the local Firestore emulator you can see that the Firestore is completely empty because we don't have any production data. This is an amazing way of working because you can do what ever you want without doing damages, but it's real life data that you most likely want to test and fix.
We are going to show you how you can export your production data to a GCP bucket or use an existing backed up bucket to import into your local Firestore.
- Firebase CLI
- Google Cloud SDK
How to install Google Cloud SDK and Firebase CLI
Login to Firebase and Google Cloud
firebase login
gcloud auth loginSee the list of your projects and connect to the on you'd like to export data from:
firebase projects:list
firebase use <your project id>
gcloud projects list
gcloud config set project <your project id>For the sake of this how to, we'll be using okr-tracker-production (production) for gcloud, and origo-okr-tracker (development) for the Firebase. The reason is that we use auth from our development Firebase instance, and not from the production instance.
If you don't already have automated backups of your production data, we will need to export the production data to a backup on GCP:
gcloud firestore export gs://okr-tracker-production.appspot.com/<backup-folder-name>Now copy the new folder to your local machine, we are going to do this from our functions folder:
cd functions
gsutil -m cp -r gs://okr-tracker-production.appspot.com/<backup-folder-name> .If you already have automated backups of your production data, you don't need to export the production data, only import it. For this application our backup folder is not part of the Firebase storage bucket:
gsutil -m cp -r gs://okr-tracker-backup/<YYYY-MM-DD>To import the production data into your local Firebase emulator, you will need a metadata-file on the root folder, named firebase-export-metadata.json:
{
"version": "8.6.0",
"firestore": {
"version": "1.11.5",
"path": "functions/<backup-folder-name>",
"metadata_file": "functions/<backup-folder-name>/<backup-folder-name>.overall_export_metadata"
}
}Start your local Firebase emulator suite with the imported data. Firebase will read the metadata-json file automatically.
firebase emulators:start --import=./We use cloud functions to backup our database every night and only keep backup of the last 14 days. If a backup is older than 14 days it gets automatically and permanently deleted from the storage bucket.
- Firebase Blaze plan
- Set IAM Permission
- Manually create a storage bucket
- Cloud function
You can follow this tutorial on how to create automated backups.
TLDR:
- Navigate to Google Cloud Console and choose your project
- Navigate to IAM & Admin - Your App Engine Service account needs the Cloud Datastore Import Export Admin role
- Navigate to Storage – Create a storage bucket – Give it a rule to delete storage that is >14 days old
- Run the command
firebase functions:config:set storage.bucket="<your-storage-bucket-name>"
This is called automated restore but we still need to manually trigger a cloud function that does the restore from the Google Cloud Console
Follow this tutorial
TLDR:
- From your Google Cloud Console navigate to PubSub
- Create a topic and name it 'restore-backup'
- Trigger the topic by publishing a message and the restore will be triggered
Gif of the process:
Src/Citation: The cloud function blog
We have a slack integration that is connected with a couple of cloud functions.
There are two cloud functions that integrate with slack
handleSlackRequest- users requesting access - slack app posts to a channel that someone wants accesshandleSlackInteractive- button actions from channel - user presses accept/reject/ignore and slack app posts to a cloud function that gives access to a user or rejects it
For these cloud functions to work you need to add a webhook url from a slack app.
Firebase steps:
- Open your gcloud console and go to IAM section
- Give your Firebase account
Pub/Sub subscriberrole
Slack steps:
- Go to slack application page and create a new app or go to your existing app
- Activate
Incoming Webhooksand create a new Webhook URL - Activate
Interactivity and Shortcutsand add a new request URL which points to your Cloud Function
Copy the webhook URL and inject it into Firebase as an environment variable:
firebase functions:config:set slack.deploymentWebhook="YOUR SLACK WEBHOOK HERE"
Request URL: https://<region>-<firebase-instance>.cloudfunctions.net/slackNotificationInteractiveOnRequest