Skip to content

Commit 983854f

Browse files
authored
Update GA tracking, DB scripts, and README.md (#470)
1 parent f6c97b2 commit 983854f

File tree

15 files changed

+221
-51
lines changed

15 files changed

+221
-51
lines changed

.env.production

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ JWT_NAME=__session
3232
# https://www.postgresql.org/docs/current/static/libpq-envars.html
3333

3434
PGHOST=/cloudsql/<project-id>:<region>:<db-instance>
35-
PGUSER=<user>
36-
PGDATABASE=<database>
37-
PGPASSWORD=<password>
35+
# PGUSER=<user>
36+
# PGDATABASE=<database>
37+
# PGPASSWORD=<password>
3838
PGAPPNAME=rsk
3939
PGSSLMODE=
4040
PGDEBUG=false

README.md

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<img src="https://api.dependabot.com/badges/status?host=github&repo=kriasoft/react-firebase-starter" alt="Dependabot" height="20" />
55
<a href="https://opencollective.com/react-firebase-starter"><img src="https://opencollective.com/react-firebase-starter/backers/badge.svg?maxAge=3600" height="20"></a>
66
<a href="https://twitter.com/ReactStarter"><img src="https://img.shields.io/twitter/follow/ReactStarter.svg?style=social&amp;label=Follow&amp;maxAge=3600" alt="Twitter" height="20"></a>
7-
<a href="https://t.me/ReactStarter"><img src="https://img.shields.io/badge/chat-Telegram-green.svg?style=social&amp;maxAge=3600" height="20"></a>
7+
<a href="https://discord.gg/2nKEnKq"><img src="https://img.shields.io/badge/chat-Discord-green.svg?style=social&amp;maxAge=3600" height="20"></a>
88
</h1>
99

1010
**React Starter Kit** _for Firebase_ is a popular project template (aka, boilerplate) for building
@@ -13,11 +13,11 @@ provided by <a href="https://cloud.google.com/">Google Cloud</a> (Cloud SQL, Clo
1313
hosting, and file storage). It allows you to save time and build upon a solid foundation and
1414
design patterns.
1515

16-
<p align="center"><strong>View</strong> <a href="https://firebase.reactstarter.com">online demo</a> (<a href="https://firebase.reactstarter.com/graphql">API</a>, <a href="https://firebase.reactstarter.com/graphql/model">data model</a>) &nbsp;|&nbsp; <strong>Follow us</strong> on <a href="https://twitter.com/ReactStarter">Twitter</a> &nbsp;|&nbsp; <strong>Get FREE support</strong> on <a href="https://t.me/ReactStarter">Telegram</a> &nbsp;|&nbsp; <a href="https://angel.co/company/kriasoft/jobs/"><strong>We're hiring!</strong></a></p>
16+
<p align="center"><strong>View</strong> <a href="https://firebase.reactstarter.com">online demo</a> (<a href="https://firebase.reactstarter.com/graphql">API</a>, <a href="https://firebase.reactstarter.com/graphql/model">data model</a>) &nbsp;|&nbsp; <strong>Follow us</strong> on <a href="https://twitter.com/ReactStarter">Twitter</a> &nbsp;|&nbsp; <strong>Get FREE support</strong> on <a href="https://discord.gg/2nKEnKq">Discord</a> &nbsp;|&nbsp; <a href="https://angel.co/company/kriasoft/jobs/"><strong>We're hiring!</strong></a></p>
1717

1818
---
1919

20-
This project was bootstraped with [React Starter Kit for Firebase][rfs] by [Kriasoft][kriasoft].
20+
This project was bootstrapped with [React Starter Kit for Firebase][rfs] by [Kriasoft][kriasoft].
2121

2222
### Tech Stack
2323

@@ -107,18 +107,38 @@ In order to re-compile GraphQL fragments, run `yarn relay` or `yarn relay --watc
107107

108108
### How to Migrate Database Schema
109109

110+
While the app is in development, you can use a simplified migration workflow by
111+
creating a backup of your existing database, making changes to the existing
112+
migration file (see `migrations/20180101000000_initial.js`), re-apply the
113+
migration and restore data from the backup file (`backup.sql`):
114+
110115
```bash
111-
$ yarn db-change # Create a new database migration file
112-
$ yarn db-migrate # Migrate database to the latest version
113-
$ yarn db-rollback # Rollback the latest migration
114-
$ yarn db-backup --env=prod # Write database backup to backup.sql
115-
$ yarn db-restore --env=dev # Restore database from backup.sql
116-
$ yarn db # Open PostgreSQL shell (for testing/debugging)
116+
$ yarn db-backup --env=dev # Or, yarn db-backup --env=test
117+
$ yarn db-reset-dev # Or, yarn db-reset-test
118+
```
119+
120+
Upon deployment to production, switch to normal migration workflow:
121+
122+
```bash
123+
$ yarn db-change <name> # Create a new database migration file
124+
$ yarn db-migrate --env=dev # Migrate database to the latest version
117125
```
118126

119-
**Note**: Appending `--env=prod` or `--env=test` flags to any of the commands above will load the
120-
corresponding database settings for the selected deployment environment from
121-
[Firebase Config API](https://firebase.google.com/docs/functions/config-env)
127+
**HINT**: Test your migration thoroughly with a local instance of the DB first
128+
(by using `--env=local` or `--env=dev` (default) flag) then apply it to your
129+
`test` or `prod` database instance using `--env=test` or `--env=prod` command
130+
argument.
131+
132+
Other helpful database scripts:
133+
134+
```bash
135+
$ yarn db-version --env=dev # Print the version number of the last migration
136+
$ yarn db-rollback --env=dev # Rollback the latest migration
137+
$ yarn db-restore --env=dev # Restore database from backup.sql
138+
$ yarn db-seed --env=dev # Seed database with test data
139+
$ yarn db --env=dev # Open Knex.js REPL shell (type ".exit" for exit)
140+
$ yarn psql --env=dev # Open PostgreSQL shell (type "\q" for exit)
141+
```
122142

123143
### How to Test
124144

knexfile.js

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,35 +7,50 @@
77
const fs = require('fs');
88
const cp = require('child_process');
99
const dotenv = require('dotenv');
10-
const { env } = require('minimist')(process.argv.slice(2));
10+
const { env = 'dev' } = require('minimist')(process.argv.slice(2));
11+
12+
function getProjectID(env) {
13+
return `example-${env}`;
14+
}
1115

1216
// Load API keys, secrets etc. from Firebase environment
1317
// https://firebase.google.com/docs/functions/config-env
14-
if (env && env !== 'dev') {
18+
if (env === 'prod' || env === 'test') {
1519
const { status, stdout } = cp.spawnSync(
1620
'firebase',
17-
[`--project=example-${env}`, 'functions:config:get'],
21+
[`--project=${getProjectID(env)}`, 'functions:config:get'],
1822
{ stdio: ['pipe', 'pipe', 'inherit'] },
1923
);
2024

2125
if (status !== 0) process.exit(status);
2226

2327
const config = JSON.parse(stdout.toString()).app;
28+
2429
Object.keys(config).forEach(key => {
2530
process.env[key.toUpperCase()] =
2631
typeof key === 'object' ? JSON.stringify(config[key]) : config[key];
2732
});
2833

29-
dotenv.config({ path: `.env.${process.env.NODE_ENV}` });
30-
// delete process.env.PGHOST;
31-
// delete process.env.PGSSLMODE;
32-
} else {
34+
process.env.PGHOST = 'X.X.X.X';
35+
process.env.PGPOST = '5432';
36+
process.env.PGSSLMODE = 'require';
37+
process.env.PGSSLCERT = `./ssl/${env}.client-cert.pem`;
38+
process.env.PGSSLKEY = `./ssl/${env}.client-key.pem`;
39+
process.env.PGSSLROOTCERT = `./ssl/${env}.server-ca.pem`;
40+
} else if (env === 'local') {
3341
dotenv.config({ path: '.env.local' });
42+
process.env.PGPORT = process.env.PGPORT || '5432';
43+
process.env.PGHOST = process.env.PGHOST || 'localhost';
44+
process.env.PGUSER = process.env.PGUSER || 'postgres';
45+
process.env.PGPASSWORD = process.env.PGPASSWORD || '';
46+
process.env.PGDATABASE = process.env.PGDATABASE || 'rsk_local';
47+
process.env.PGSSLMODE = process.env.PGSSLMODE || 'disable';
3448
}
3549

50+
console.log('Environment:', env);
3651
dotenv.config({ path: '.env' });
3752

38-
// Knex configuration
53+
// Knex configuration that is used with DB migration scripts etc.
3954
// http://knexjs.org/#knexfile
4055
module.exports = {
4156
client: 'pg',

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,6 @@
103103
"test": "react-app test",
104104
"lint": "eslint --ignore-path .gitignore --ignore-pattern \"!**/.*\" .",
105105
"lint-fix": "eslint --ignore-path .gitignore --ignore-pattern \"!**/.*\" --fix . && yarn run prettier --write \"**/*.{js,json}\"",
106-
"db": "node ./scripts/db",
107106
"db-backup": "node ./scripts/db-backup",
108107
"db-restore": "node ./scripts/db-restore",
109108
"db-change": "knex migrate:make",
@@ -114,6 +113,8 @@
114113
"db-reset-dev": "yarn db-rollback --env=dev && yarn db-migrate --env=dev && yarn db-restore --env=dev",
115114
"db-reset-test": "yarn db-rollback --env=test && yarn db-migrate --env=test && yarn db-restore --env=test",
116115
"db-reset-prod": "yarn db-rollback --env=prod && yarn db-migrate --env=prod && yarn db-restore --env=prod",
116+
"db": "node --experimental-repl-await ./scripts/db",
117+
"psql": "node ./scripts/psql",
117118
"deploy": "yarn run deploy-test",
118119
"deploy-test": "node ./scripts/pre-deploy --env=test && firebase --project=example-test deploy && node ./scripts/post-deploy --env=test",
119120
"deploy-prod": "node ./scripts/pre-deploy --env=prod && firebase --project=example-prod deploy && node ./scripts/post-deploy --env=prod"

scripts/db.js

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,20 @@
44
* Copyright (c) 2015-present Kriasoft | MIT License
55
*/
66

7-
const cp = require('child_process');
7+
const repl = require('repl');
8+
const knex = require('knex');
9+
const config = require('../knexfile');
810

9-
// Load environment variables (PGHOST, PGUSER, etc.)
10-
require('../knexfile');
11+
global.db = knex(config);
1112

12-
// Ensure that the SSL key file has correct permissions
13-
if (process.env.PGSSLKEY) {
14-
cp.spawnSync('chmod', ['0600', process.env.PGSSLKEY], { stdio: 'inherit' });
15-
}
16-
17-
// Launch interactive terminal for working with Postgres
18-
cp.spawn('psql', { stdio: 'inherit' });
13+
global.db
14+
.raw('select current_database(), version()')
15+
.then(({ rows: [x] }) => {
16+
console.log('Connected to', x.current_database);
17+
console.log(x.version);
18+
repl.start('#> ').on('exit', process.exit);
19+
})
20+
.catch(err => {
21+
console.error(err);
22+
process.exit(1);
23+
});

scripts/psql.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/**
2+
* React Starter Kit for Firebase
3+
* https://github.com/kriasoft/react-firebase-starter
4+
* Copyright (c) 2015-present Kriasoft | MIT License
5+
*/
6+
7+
const cp = require('child_process');
8+
9+
// Load environment variables (PGHOST, PGUSER, etc.)
10+
require('../knexfile');
11+
12+
// Ensure that the SSL key file has correct permissions
13+
if (process.env.PGSSLKEY) {
14+
cp.spawnSync('chmod', ['0600', process.env.PGSSLKEY], { stdio: 'inherit' });
15+
}
16+
17+
// Launch interactive terminal for working with Postgres
18+
cp.spawn('psql', { stdio: 'inherit' });

src/common/App.js

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import React from 'react';
88
import CssBaseline from '@material-ui/core/CssBaseline';
99
import { QueryRenderer } from 'react-relay';
10+
import { ROOT_ID, REF_KEY } from 'relay-runtime';
1011
import { MuiThemeProvider } from '@material-ui/core/styles';
1112

1213
import theme from '../theme';
@@ -36,14 +37,25 @@ class App extends React.PureComponent {
3637
state = { error: null };
3738

3839
componentDidRender = () => {
39-
const { history, title, config } = this.props;
40+
const { history, location, startTime, title, config, relay } = this.props;
4041
window.document.title = title;
4142

42-
// Track page views
43-
gtag('config', config.gaTrackingId, { transport_type: 'beacon' });
44-
// fb(FB => FB.AppEvents.logPageView());
45-
46-
const scrollY = getScrollPosition(history.location.key);
43+
// Get the current user's ID
44+
const root = relay.getStore().getSource().get(ROOT_ID); // prettier-ignore
45+
const userId = root && root.me ? atob(root.me[REF_KEY]).substr(5) : '';
46+
47+
// Track page views, render time, etc.
48+
gtag('config', config.gaTrackingId, {
49+
transport_type: 'beacon',
50+
user_id: userId,
51+
});
52+
gtag('event', 'timing_complete', {
53+
name: 'load',
54+
value: Math.round(performance.now() - startTime),
55+
event_category: 'Render Complete',
56+
});
57+
58+
const scrollY = getScrollPosition(location.key);
4759

4860
if (scrollY && history.action === 'POP') {
4961
window.scrollTo(0, scrollY);

src/icons/Facebook.js

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,18 @@ const Facebook = React.forwardRef(function Facebook(props, ref) {
1212
return (
1313
<SvgIcon
1414
ref={ref}
15-
role="img"
1615
width={size}
1716
height={size}
1817
viewBox="0 0 256 256"
18+
titleAccess="Facebook icon"
19+
htmlColor="#4172B8"
1920
{...other}
2021
>
21-
<g>
22-
<path
23-
d="M241.871,256.001 C249.673,256.001 256,249.675 256,241.872 L256,14.129 C256,6.325 249.673,0 241.871,0 L14.129,0 C6.324,0 0,6.325 0,14.129 L0,241.872 C0,249.675 6.324,256.001 14.129,256.001 L241.871,256.001"
24-
fill="#395185"
25-
></path>
26-
<path
27-
d="M176.635,256.001 L176.635,156.864 L209.912,156.864 L214.894,118.229 L176.635,118.229 L176.635,93.561 C176.635,82.375 179.742,74.752 195.783,74.752 L216.242,74.743 L216.242,40.188 C212.702,39.717 200.558,38.665 186.43,38.665 C156.932,38.665 136.738,56.67 136.738,89.736 L136.738,118.229 L103.376,118.229 L103.376,156.864 L136.738,156.864 L136.738,256.001 L176.635,256.001"
28-
fill="#FFFFFF"
29-
></path>
30-
</g>
22+
<path d="M241.871,256.001 C249.673,256.001 256,249.675 256,241.872 L256,14.129 C256,6.325 249.673,0 241.871,0 L14.129,0 C6.324,0 0,6.325 0,14.129 L0,241.872 C0,249.675 6.324,256.001 14.129,256.001 L241.871,256.001"></path>
23+
<path
24+
d="M176.635,256.001 L176.635,156.864 L209.912,156.864 L214.894,118.229 L176.635,118.229 L176.635,93.561 C176.635,82.375 179.742,74.752 195.783,74.752 L216.242,74.743 L216.242,40.188 C212.702,39.717 200.558,38.665 186.43,38.665 C156.932,38.665 136.738,56.67 136.738,89.736 L136.738,118.229 L103.376,118.229 L103.376,156.864 L136.738,156.864 L136.738,256.001 L176.635,256.001"
25+
fill="#FFFFFF"
26+
></path>
3127
</SvgIcon>
3228
);
3329
});

src/icons/GitHub.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* React Starter Kit for Firebase
3+
* https://github.com/kriasoft/react-firebase-starter
4+
* Copyright (c) 2015-present Kriasoft | MIT License
5+
*/
6+
7+
import React from 'react';
8+
import SvgIcon from '@material-ui/core/SvgIcon';
9+
10+
const GitHub = React.forwardRef(function GitHub(props, ref) {
11+
return (
12+
<SvgIcon
13+
ref={ref}
14+
viewBox="0 0 24 24"
15+
titleAccess="GitHub icon"
16+
htmlColor="#181717"
17+
{...props}
18+
>
19+
<path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12" />
20+
</SvgIcon>
21+
);
22+
});
23+
24+
export default GitHub;

src/icons/Instagram.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/**
2+
* React Starter Kit for Firebase
3+
* https://github.com/kriasoft/react-firebase-starter
4+
* Copyright (c) 2015-present Kriasoft | MIT License
5+
*/
6+
7+
import React from 'react';
8+
import SvgIcon from '@material-ui/core/SvgIcon';
9+
10+
const Instagram = React.forwardRef(function Instagram(props, ref) {
11+
const { size = 24, ...other } = props;
12+
return (
13+
<SvgIcon
14+
ref={ref}
15+
width={size}
16+
height={size}
17+
viewBox="0 0 24 24"
18+
titleAccess="Instagram icon"
19+
htmlColor="#E4405F"
20+
{...other}
21+
>
22+
<path d="M12 0C8.74 0 8.333.015 7.053.072 5.775.132 4.905.333 4.14.63c-.789.306-1.459.717-2.126 1.384S.935 3.35.63 4.14C.333 4.905.131 5.775.072 7.053.012 8.333 0 8.74 0 12s.015 3.667.072 4.947c.06 1.277.261 2.148.558 2.913.306.788.717 1.459 1.384 2.126.667.666 1.336 1.079 2.126 1.384.766.296 1.636.499 2.913.558C8.333 23.988 8.74 24 12 24s3.667-.015 4.947-.072c1.277-.06 2.148-.262 2.913-.558.788-.306 1.459-.718 2.126-1.384.666-.667 1.079-1.335 1.384-2.126.296-.765.499-1.636.558-2.913.06-1.28.072-1.687.072-4.947s-.015-3.667-.072-4.947c-.06-1.277-.262-2.149-.558-2.913-.306-.789-.718-1.459-1.384-2.126C21.319 1.347 20.651.935 19.86.63c-.765-.297-1.636-.499-2.913-.558C15.667.012 15.26 0 12 0zm0 2.16c3.203 0 3.585.016 4.85.071 1.17.055 1.805.249 2.227.415.562.217.96.477 1.382.896.419.42.679.819.896 1.381.164.422.36 1.057.413 2.227.057 1.266.07 1.646.07 4.85s-.015 3.585-.074 4.85c-.061 1.17-.256 1.805-.421 2.227-.224.562-.479.96-.899 1.382-.419.419-.824.679-1.38.896-.42.164-1.065.36-2.235.413-1.274.057-1.649.07-4.859.07-3.211 0-3.586-.015-4.859-.074-1.171-.061-1.816-.256-2.236-.421-.569-.224-.96-.479-1.379-.899-.421-.419-.69-.824-.9-1.38-.165-.42-.359-1.065-.42-2.235-.045-1.26-.061-1.649-.061-4.844 0-3.196.016-3.586.061-4.861.061-1.17.255-1.814.42-2.234.21-.57.479-.96.9-1.381.419-.419.81-.689 1.379-.898.42-.166 1.051-.361 2.221-.421 1.275-.045 1.65-.06 4.859-.06l.045.03zm0 3.678c-3.405 0-6.162 2.76-6.162 6.162 0 3.405 2.76 6.162 6.162 6.162 3.405 0 6.162-2.76 6.162-6.162 0-3.405-2.76-6.162-6.162-6.162zM12 16c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4zm7.846-10.405c0 .795-.646 1.44-1.44 1.44-.795 0-1.44-.646-1.44-1.44 0-.794.646-1.439 1.44-1.439.793-.001 1.44.645 1.44 1.439z" />
23+
</SvgIcon>
24+
);
25+
});
26+
27+
export default Instagram;

0 commit comments

Comments
 (0)